jQuery .ajax和同源策略

时间:2012-08-27 20:20:55

标签: jquery ajax json jsonp same-origin-policy

我有一个正在运行的HTML5 / JS应用程序,我正在尝试移植到浏览器进行演示。该应用程序是为在车辆中运行而构建的,并使用车辆制造商的网络API来获取/发布请求。

对于浏览器版本,我正在尝试使用jQuery来获取/发布。但是,我马上遇到了问题。

XMLHttpRequest cannot load http://<API I AM CALLING>. Origin null is not allowed by Access-Control-Allow-Origin.

我已经研究过相同的原始政策,但仍然没有完全理解它。我可以浏览到正在使用的URL,并查看我正在尝试检索的JSON。

环顾网络,很多人建议在我的ajax调用中将JSONP指定为dataType。我给了这个镜头,没有成功。

            $.ajax({
                url: url,
                type: "GET",
                dataType: "jsonp",
                success: function (data, textStatus, jqXHR) {
                    log("success getting JSON from " + url);
                    success(data);
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    log("error getting JSON from " + url + ", code " + JSON.stringify(jqXHR));
                    log("textStatus is " + textStatus);
                    log("errorThrown is " + errorThrown);
                },
            });

我的控制台中显示错误:

Uncaught SyntaxError: Unexpected token : 

之后,使用我的错误回调。

error getting JSON from http://<API I AM CALLING>, code {"readyState":4,"status":200,"statusText":"success"}
textStatus is parsererror
errorThrown is Error: jQuery180006523256213404238_1346098086632 was not called 

看起来服务器正在响应我需要的JSON数据。但是,我猜测jQuery期望这个数据被包装在一个函数中,所以它无法解析它。

我无法控制我正在调用其API的服务器。由于数据将返回浏览器,我觉得必须有一些方法可以访问它。

注意:
应用程序仅针对webkit浏览器,我不需要支持任何其他浏览器。将dataType保留为“json”只会导致Chrome出现问题,但由于安全策略不同,Safari似乎工作正常。寻找代码解决方法,而不是简单地使用特殊参数启动Chrome。即使我在Apache上托管我的代码,Chrome仍然会发生这种情况,所以它不仅限于我尝试在本地打开index.html。

1 个答案:

答案 0 :(得分:2)

一种可能的解决方案是编写代理所需JSON服务的服务并返回JSONP。我写了很多像这样的代理服务,所以我可以绕过相同的原始政策。

例如:http://high-cloud-3702.heroku.com/

此服务是城市词典的jsonp代理。

你可以很容易地在Sinatra中编写这样的代理,并在Heroku上免费托管。

这样的代理的关键是这段代码:

get '/' do
  callback = params.delete('callback') # jsonp
  json = <function_to_get_data_here>.to_json

  if callback
    content_type :js
    response = "#{callback}(#{json})" 
  else
    content_type :json
    response = json
  end
  response
end