2012-08-27 150 views
2

我有一个正在运行的HTML5/JS应用程序,我试图移植到浏览器进行演示。该应用程序被构建为在车辆中运行,并使用车辆制造商的网络API获取/发送请求。jQuery .ajax和相同来源策略

对于浏览器版本,我试图使用jQuery的get/post。但是,我立即遇到问题。

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

你不能简单的从'json'改变'jsonp'没有更新API返回有效'jsonp'。 'JSON'!='JSONP' –

+0

我意识到这一点,但它确实绕过了相同的原始策略,服务器能够响应我需要的JSON。我只需要弄清楚如何获得这些数据。 – Danny

+0

如果它不是有效的'JSONP',你就无法得到它。另一个选择是使用'JSON'数据类型并让服务器返回CORS头文件。 –

回答

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 
+0

OP可以从他的服务器返回JSON。 – BNL

+0

我想我认为OP没有控制他打电话给他的服务器时,他说:“我无法控制其服务器的API我打电话”。但是,如果他可以在与该服务存在的相同域中托管他的应用程序,则只需进行常规的JSON调用即可...... – meub