2

I have some regularly-updated CSV files on Box that I would like to display on a website. My plan was to create the table with html, then read the CSV file with d3 and update the contents of the table. If the CSV data were on GitHub, I could do something like this:

d3.csv(data_url).then(create_table);
function create_table(data) {
   <code to update a table>
}

However, that doesn't seem to work with a Box URL. I can generate a URL for the data on Box with the format "https://xxxxxxxx.box.com/shared/static/xxxxxxxxx.csv". Going to that link directly will download the CSV file, but inserting it into the code above produces a "Cross-Origin Request Blocked" error. Is this possible? Since the CSV files update hourly, it would be best if I could read directly from Box to my website, rather than moving the data elsewhere.

1
  • 1
    Do you have a Box API so you can fetch the CSV file? Commented May 14 at 21:31

1 Answer 1

4

Box’s shared static file URLs (e.g. https://xxxxxxxx.box.com/shared/static/xxxxxxxxx.csv) do not send CORS headers, and:

They force a file download via Content-Disposition: attachment

They do not allow cross-origin AJAX/fetch/XHR requests like d3.csv()

Hence, when you use D3 or fetch() from your website, the browser blocks it due to CORS policy.

You can test this approach temporarily using a public CORS proxy like:

const proxy = "https://cors-anywhere.herokuapp.com/";
const url = proxy + "https://xxxxxxxx.box.com/shared/static/xxxxxxxxx.csv";

d3.csv(url).then(create_table);

OR

Set up a backend (Node.js, Laravel, etc.) to periodically download the CSV from Box, store it locally, and serve it with proper CORS headers.

Laravel example:

Route::get('/csv-data', function () {
    $url = 'https://xxxxxxxx.box.com/shared/static/xxxxxxxxx.csv';
    $csv = file_get_contents($url);
    return response($csv)->header('Content-Type', 'text/csv');
});

Example in Node.js:

const express = require('express');
const axios = require('axios');
const app = express();

app.get('/csv-data', async (req, res) => {
  const boxUrl = 'https://xxxxxxxx.box.com/shared/static/xxxxxxxxx.csv';
  const response = await axios.get(boxUrl, { responseType: 'stream' });
  response.data.pipe(res);
});

app.listen(3000, () => console.log('Proxy server running'));

React/D3 side:

d3.csv('http://yourdomain.com/csv-data').then(create_table);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the suggestions. I'll look into these options a bit more. One other complication I just realized: apparently, when the file is updated each hour, the filename stays the same but the direct link ceases to work. At least as far as I can tell.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.