首页 > 解决方案 > 如何在本地文件:// URL 上显示来自 javascript 的世界地图

问题描述

我有一个离线 Javascript 应用程序,使用画布中的正交投影在世界地图上绘制日食区域。它是 2013 年 d3.v3.js,使用存储在 world-110m.json 中的世界地图。它在网络服务器中使用时工作正常(即 http://localaddress/....),但在使用 file:// 时(例如在不允许 iOS 等网络服务器的设备上),它会发出错误:

跨域请求被阻止:同源策略不允许读取位于 file:///mylocalpath/world-110m.json 的远程资源。(原因:CORS 请求不是 http)

以前没问题,但在较新的浏览器中会发生此错误。检查 d3.v3.js 中的代码会发现用于加载世界地图的非常复杂的代码。

我试图通过将 json 复制到 js 并将 'var theworld=' 附加到 json 代码并在代码中添加一行来在本地加载此 JSON:

<script src="world-110m.js"></script>

加载时没有错误,但是如何在不使用 XMLHttpRequest() 或其他复杂代码的情况下加载这个 json(这只是一个 Javascript)对象?

选项二:我发现了更新的版本 op topojson,但没有工作示例可以仅加载简单的海岸线世界地图,显示内容形状。

有没有一种简单的方法可以从包含 javascripts 的本地 file:// html 文件在 javascript 画布中绘制世界地图?

标签: javascript

解决方案


与此同时,我找到了答案。

我加载世界地图 json 文件,就好像它是一个 js 文件(它实际上是一个数组),通过将它分配给一个变量来添加它:“var theworld = [the very long world map json]”(不带引号)并包含它使用 html 中的 js 扩展名:

<script src="world-110m.js"></script>

原始代码是:

d3.json("./world-110m.json", function(error, world) {
console.log(topojson.object(world, world.objects.land));
var land = topojson.object(world, world.objects.land),
  globe = {type: "Sphere"};
  context = canvas.node().getContext("2d");

  context.strokeStyle = '#766951';

  context.fillStyle = '#88C0FF';
  context.beginPath(), path.context(context)(globe), context.fill(),       context.stroke();

  context.fillStyle = '#d7c7ad';
  context.beginPath(), path.context(context)(land), context.fill(), context.stroke();

});

我通过消除对 d3.json 的调用和结束 }); 替换了这个,将变量名 'world' 替换为 'theworld' (后者可能没有必要我可以使用变量名 'world' 而不是 'theworld'在修改后的世界地图 js(on).)。

console.log(topojson.object(theworld, theworld.objects.land));

var land = topojson.object(theworld, theworld.objects.land),
  globe = {type: "Sphere"};
  context = canvas.node().getContext("2d");

  context.strokeStyle = '#766951';

  context.fillStyle = '#88C0FF';
  context.beginPath(), path.context(context)(globe), context.fill(), context.stroke();

  context.fillStyle = '#d7c7ad';
  context.beginPath(), path.context(context)(land), context.fill(), context.stroke();

现在它在 file:// 和 http(s):// 中都能完美运行。

对于本地网站来说,被阻止的跨域请求真的很奇怪。当它在本地是纯的时,这个不应该被阻塞。


推荐阅读