24

我有一个问题...我尝试在http://api.master18.tiket.com/search/autocomplete/hotel?q=mah&token=90d2fad44172390b11527557e6250e50&secretkey=83e2f0484edbd2ad6fc9888c1e30ea44&output=json ”中获取 json api

当我尝试使用此代码进入离线模式时(这意味着我在记事本中复制该 json API 并在我的本地主机中调用它)...

function getLast(){
        $.ajax({
            url:"http://localhost/tickets/json/api_airport.json",
            type:'GET',
            dataType:"json",
            success:function(data){console.log(data.results.result[1].category);}
        });
    }

它运行完美。:)

但是当我尝试使用以下代码访问真实网址(“ http://api.master18.tiket.com/search/autocomplete/hotel?q=mah&token=90d2fad44172390b11527557e6250e50&secretkey=83e2f0484edbd2ad6fc9888c1e30ea44&output=json ”)时:

$.ajax({
            url:"http://api.master18.tiket.com/search/autocomplete/hotel?q=mah&token=90d2fad44172390b11527557e6250e50&secretkey=83e2f0484edbd2ad6fc9888c1e30ea44&output=json",
            type:'GET',
            crossDomain:true,
            beforeSend: function(x) {
                if(x && x.overrideMimeType) {
                    x.overrideMimeType("application/j-son;charset=UTF-8");
                }
            },
            success:function(data){console.log("Success");}
        });

然后在我的 google chrome javascript 控制台中,出现这样的错误:“ XMLHttpRequest无法加载http://api.master18.tiket.com/search/autocomplete/hotel?q=mah&token=90d2fad44172390b11527557e6250e50&secretkey=83e2f0484edbd2ad6fc9888c1e30ea44&output=json。来源://localhost ) 是 Access-Control-Allow-Origin 不允许的。”

我知道,这一定是跨域问题,有人可以帮助我吗?nb:一些代码,我从堆栈溢出社区获得....谢谢 :)

4

3 回答 3

48

你有两种前进的方式:

JSONP


如果此 API 支持JSONP,则解决此问题的最简单方法是添加&callback到 URL 的末尾。你也可以试试&callback=。如果这不起作用,则意味着 API 不支持JSONP,因此您必须尝试其他解决方案。

代理脚本


您可以在与您的网站相同的域上创建代理脚本,以避免跨域问题。这仅适用于 HTTP URL,不适用于 HTTPS URL,但如果您需要修改它应该不会太难。

<?php
// File Name: proxy.php
if (!isset($_GET['url'])) {
    die(); // Don't do anything if we don't have a URL to work with
}
$url = urldecode($_GET['url']);
$url = 'http://' . str_replace('http://', '', $url); // Avoid accessing the file system
echo file_get_contents($url); // You should probably use cURL. The concept is the same though

然后你只需用 jQuery 调用这个脚本。一定要urlencode网址。

$.ajax({
    url      : 'proxy.php?url=http%3A%2F%2Fapi.master18.tiket.com%2Fsearch%2Fautocomplete%2Fhotel%3Fq%3Dmah%26token%3D90d2fad44172390b11527557e6250e50%26secretkey%3D83e2f0484edbd2ad6fc9888c1e30ea44%26output%3Djson',
    type     : 'GET',
    dataType : 'json'
}).done(function(data) {
    console.log(data.results.result[1].category); // Do whatever you want here
});

为什么


由于 XMLHttpRequest 同源策略,您会收到此错误,这基本上归结为将 ajax 请求限制为具有不同端口、域或协议的 URL。此限制用于防止跨站点脚本 (XSS) 攻击。

更多信息

我们的解决方案以不同的方式绕过这些问题。

JSONP使用将脚本标签指向 JSON(包装在 javascript 函数中)以接收 JSON 的能力。JSONP 页面被解释为 javascript,并被执行。JSON 将传递给您指定的函数。

代理脚本通过欺骗浏览器来工作,因为您实际上是在请求与您的页面同源的页面。实际的跨域请求发生在服务器端。

于 2012-10-02T02:01:39.627 回答
4

我用一个简单的 nginx 代理修复了这个(用于开发)......

# /etc/nginx/sites-enabled/default
server {
  listen 80;
  root /path/to/Development/dir;
  index index.html;

  # from your example
  location /search {
    proxy_pass http://api.master18.tiket.com;
  }
}
于 2013-07-27T20:13:17.177 回答
2

彻底阅读jQuery AJAX 跨域似乎表明您正在查询的服务器正在返回一个禁止跨域 json 请求的标头字符串。检查您收到的响应的标头,以查看是否设置了 Access-Control-Allow-Origin 标头,以及其值是否将跨域请求限制到本地主机。

于 2012-10-02T02:00:17.850 回答