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.
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);