在file协议下进行JSON/JSONP XHR请求

3
我正在编写一个JavaScript应用程序,将其托管在“file:”协议上(即:应用程序只是一个html、css和javascript文件夹,在我的硬盘上的某个位置)。当我尝试使用普通的XHR请求时,由于同源策略的限制,它们失败了。
因此,我的问题是,如何以描述的方式请求JSON / JSONP文件是最好的方法?
注意:到目前为止,我已经使用硬编码回调函数获取了所有的jsonp文件,但我希望能够为这些请求使用动态回调函数..有没有一种方法可以实现这一点?

您有任何浏览器要求吗? - Hemlock
2
它应该在尽可能多的浏览器上运行。 - erikvold
由于您无法通过请求“file:”主机来返回“Access-Control-Allow-Origin”标头,因此使用CORS永远不会起作用。 - inf3rno
2个回答

7

这有点粗糙,但它可以让您获得动态回调。基本上,它依赖于 file: 传输将非常快速。它设置了一个请求队列,并逐个发送它们。这是我能想到的唯一确保正确响应和回调可以链接(以保证顺序)的方法。希望有人能想出更好的办法,但如果不能动态生成响应,这就是我所能做的最好的。

var JSONP = {
  queue: [],
  load: function(file, callback, scope) {
      var head = document.getElementsByTagName('head')[0];
      var script = document.createElement('script');
      script.type = "text/javascript";
      script.src = file;
      head.appendChild(script);
  },

  request: function(file, callback, scope) {
      this.queue.push(arguments);
      if (this.queue.length == 1) {
          this.next();
      }
  },

  response: function(json) {
      var requestArgs = this.queue.shift();
      var file = requestArgs[0];
      var callback = requestArgs[1];
      var scope = requestArgs[2] || this;
      callback.call(scope, json, file);

      this.next();
  },

  next: function() {
      if (this.queue.length) {
          var nextArgs = this.queue[0];
          this.load.apply(this, nextArgs);
      }
  }

};

我所做的测试如下:

window.onload = function() {
  JSONP.request('data.js', function(json, file) { alert("1 " + json.message); });
  JSONP.request('data.js', function(json, file) { alert("2 " + json.message); });
}

Data.js

JSONP.response({
  message: 'hello'
});

@Erik 我并没有做出那个假设。实际上,在发送下一个请求之前,我正在等待返回。相反,我假设请求会很快完成。然而,顺序不会成为问题。 - Hemlock
@Erik... 我想我也假设不会出现错误 ;) - Hemlock
这是一个不错的解决方案,但我希望能看到一个不需要排队请求的解决方案,但当使用 file: 时,这并不太糟糕,就像你所说的那样。 - erikvold
我喜欢你的解决方案!它不是一个XHR请求,但看起来它做了OP所要求的事情。 - Gerrat

1

出于安全原因,Chrome对从file:// URL发起ajax调用有非常严格的限制。他们知道这会破坏本地运行的应用程序,并且已经进行了大量辩论,但这就是今天的现状。

在Firefox中,从文件URL中使用Ajax可以正常工作,只需注意返回代码不是HTTP状态代码;即0表示成功,而不是200-299 + 304。

IE以与Chrome和Firefox不同的方式处理这些安全问题,我希望其他浏览器也会有自己的方法。Web和桌面应用程序之间的边界是非常棘手的领域。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接