【问题标题】:making json/jsonp xhr requests on the file: protocol对文件发出 json/jsonp xhr 请求:协议
【发布时间】:2011-06-03 03:32:29
【问题描述】:

我正在编写一个 javascript 应用程序,它将托管在 file: 协议上(即:该应用程序只是我硬盘上某个位置的 html、css 和 javascript 文件夹)。当我尝试正常的 XHR 请求时,它们会因为相同的源策略而失败。

所以我的问题是,使用上述应用程序请求 json/jsonp 文件的最佳方式是什么?

注意:到目前为止,我的所有 jsonp 文件都使用硬编码的回调函数,但我希望能够对这些请求使用动态回调函数。有没有办法做到这一点?

【问题讨论】:

  • 您对浏览器有什么要求吗?
  • 它应该可以在尽可能多的浏览器上运行。
  • 使用 CORS 将永远无法工作,因为您无法通过请求 file: 主机返回 Access-Control-Allow-Origin 标头。

标签: javascript html json xmlhttprequest file-uri


【解决方案1】:

出于安全原因,Chrome 对从 file:// url 进行 ajax 调用有非常严格的限制。他们知道这会破坏在本地运行的应用程序,并且有 a lot of debate 关于替代方案,但这就是今天的情况。

Ajax 在 Firefox 中的文件 url 工作正常,请注意返回码不是 http 状态码;即,0 是成功,而不是 200-299 + 304。

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

【讨论】:

    【解决方案2】:

    这有点像打架的工作,但它会为您提供动态回调。基本上它依赖于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); });
    }
    

    数据.js

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

    【讨论】:

    • @Erik 我没有做出这样的假设。在发送下一个请求之前,我实际上是在等待返回。相反,我假设请求会很快。但是,订单将不是问题。
    • @Erik ...我想我也假设不会有错误;)
    • 这是一个不错的解决方案,虽然我很想看到一个不需要排队请求的解决方案,但就像你说的那样,在使用 file: 时还不错。
    • 我喜欢你的解决方案!这不是 XHR 请求;但看起来它符合 OP 的要求。
    猜你喜欢
    • 2016-03-19
    • 2013-10-29
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 2014-05-21
    • 1970-01-01
    相关资源
    最近更新 更多