D3.js带图例散点图CORS报错求助:本地CSV加载失败
解决D3.js本地加载CSV的CORS问题
问题描述
直接本地打开HTML文件时出现CORS报错,无法加载data.csv:
Access to fetch at 'file:///C:/Users/Muhy/Dropbox/Scripts/data.csv' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome, https, chrome-untrusted. Failed to load resource: net::ERR_FAILED data.csv:1 Uncaught (in promise) TypeError: Failed to fetch at cc (d3.v7.min.js:2:100754) at Object.csv (d3.v7.min.js:2:100878) at data-script.js:20:4 d3.v7.min.js:2
已启用CORS Unblock扩展,但问题未解决。
相关文件内容
1. data.csv
x,y,z 1,2,3 2,4,6 3,6,9 4,8,12 5,10,15 6,12,18 7,14,21 8,16,24 9,18,27 10,20,30
2. style-sheet.css
.legend { font-family: Arial, sans-serif; font-size: 12px; }
3. HTML文件
<html> <head> <title>D3 Legend Scatterplot</title> <link rel="stylesheet" href="style-sheet.css"> </head> <body> <script src="https://d3js.org/d3.v7.min.js"></script> <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.25.6/d3-legend.min.js"></script> <svg id="scatterplot"></svg> <div id="legend"></div> <script src="data-script.js"></script> </body> </html>
4. data-script.js
// Set up the scatter plot. var margin = { top: 20, right: 20, bottom: 30, left: 40 }; var width = 600 - margin.left - margin.right; var height = 400 - margin.top - margin.bottom; var x = d3.scaleLinear() .range([0, width]); var y = d3.scaleLinear() .range([height, 0]); var color = d3.scaleSequential(d3.interpolateViridis); var svg = d3.select("#scatterplot") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); d3.csv("data.csv").then(function (data, error) { if (error) throw error; data.forEach(function (d) { d.x = +d.x; d.y = +d.y; }); x.domain(d3.extent(data, function (d) { return d.x; })).nice(); y.domain(d3.extent(data, function (d) { return d.y; })).nice(); color.domain(d3.extent(data, function (d) { return d.z; })); svg.selectAll(".dot") .data(data) .enter().append("circle") .attr("class", "dot") .attr("r", 3.5) .attr("cx", function (d) { return x(d.x); }) .attr("cy", function (d) { return y(d.y); }) .style("fill", function (d) { return color(d.z); }); // Set up the legend. var legend = d3.legendColor() .labelFormat(d3.format(".2f")) .title("Z Value") .scale(color); svg.append("g") .attr("class", "legend") .call(legend); });
解决方案
1. 使用本地HTTP服务器(推荐)
浏览器禁止file://协议发起跨域请求,最稳妥的方法是用本地HTTP服务器托管文件:
- 若安装Python 3,打开命令行进入文件所在目录,运行:
python -m http.server 8000 - 若安装Python 2,运行:
python -m SimpleHTTPServer 8000 - 之后在浏览器访问
http://localhost:8000/你的HTML文件名.html即可正常加载CSV。
2. 修改Chrome启动参数
通过修改Chrome启动参数,允许file://协议的跨域请求:
- 关闭所有Chrome窗口
- 右键点击Chrome快捷方式,选择「属性」,在「目标」栏末尾添加:
--allow-file-access-from-files(注意前面有空格) - 启动Chrome后再打开本地HTML文件。
3. 内嵌CSV数据到JS文件(临时方案)
把CSV内容直接转为JS对象数组,替换d3.csv("data.csv")的请求逻辑:
// 替换原d3.csv请求部分 const data = [ {x: 1, y: 2, z: 3}, {x: 2, y: 4, z: 6}, {x: 3, y: 6, z: 9}, {x: 4, y: 8, z: 12}, {x: 5, y: 10, z: 15}, {x: 6, y: 12, z: 18}, {x: 7, y: 14, z: 21}, {x: 8, y: 16, z: 24}, {x: 9, y: 18, z: 27}, {x: 10, y: 20, z: 30} ]; // 原数据处理及绘图逻辑直接接在这里 data.forEach(function (d) { d.x = +d.x; d.y = +d.y; }); x.domain(d3.extent(data, function (d) { return d.x; })).nice(); y.domain(d3.extent(data, function (d) { return d.y; })).nice(); color.domain(d3.extent(data, function (d) { return d.z; })); // ... 后续绘图代码保持不变
内容的提问来源于stack exchange,提问作者user11658838
相关产品推荐
相关产品推荐

