将jQuery帖子发送到Google API的Access-Control-Allow-Origin错误


143

我读了很多有关“ Access-Control-Allow-Origin”错误的信息,但我不明白我该如何解决:(

我正在使用Google Moderator API,但是当我尝试 添加新系列时,收到以下消息:

XMLHttpRequest cannot load 
https://www.googleapis.com/moderator/v1/series?key=[key]
&data%5Bdescription%5D=Share+and+rank+tips+for+eating+healthily+on+the+cheaps!
&data%5Bname%5D=Eating+Healthy+%26+Cheap
&data%5BvideoSubmissionAllowed%5D=false. 
Origin [my_domain] is not allowed by Access-Control-Allow-Origin.

我尝试使用和不使用回调参数,都尝试将“ Access-Control-Allow-Origin *”添加到标题中。而且我不知道如何在这里使用$ .getJSON(如果适用),因为我必须添加Authorization标头,而且如果没有$ .ajax中的beforeCall,我也不知道该怎么做:/

这个黑暗的你有光吗?

那是代码:

<script src="http://www.google.com/jsapi"></script>

<script type="text/javascript">

var scope = "https://www.googleapis.com/auth/moderator";
var token = '';

function create(){
     if (token == '')
      token = doCheck();

     var myData = {
      "data": {
        "description": "Share and rank tips for eating healthily on the cheaps!", 
        "name": "Eating Healthy & Cheap", 
        "videoSubmissionAllowed": false
      }
    };

    $.ajax({

        url: 'https://www.googleapis.com/moderator/v1/series?key='+key,
        type: 'POST',
        callback: '?',
        data: myData,
        datatype: 'application/json',
        success: function() { alert("Success"); },
        error: function() { alert('Failed!'); },
        beforeSend: setHeader

    });
}

function setHeader(xhr) {

  xhr.setRequestHeader('Authorization', token);
}

function doLogin(){ 
    if (token == ''){
       token = google.accounts.user.login(scope);
    }else{
       alert('already logged');
    }
}


function doCheck(){             
    token = google.accounts.user.checkLogin(scope);
    return token;
}
</script>
...
...
<div data-role="content">
    <input type="button" value="Login" onclick="doLogin();">
    <input type="button" value="Get data" onclick="getModerator();">
    <input type="button" value="Create" onclick="create();">
</div><!-- /content -->

1
您能否将您的代码更完整一些?我无法运行您的代码。
侯赛因·阿卡贾尼

Answers:


249

我解决了将dataType参数修改为dataType:'jsonp'并添加crossDomain:true的Access-Control-Allow-Origin错误

$.ajax({

    url: 'https://www.googleapis.com/moderator/v1/series?key='+key,
    data: myData,
    type: 'GET',
    crossDomain: true,
    dataType: 'jsonp',
    success: function() { alert("Success"); },
    error: function() { alert('Failed!'); },
    beforeSend: setHeader
});

20
我不认为这crossDomain:true是必需的。我的理解是,仅当您在自己的域上发出请求但希望jQuery将其视为跨域请求时才有必要。
亚历克斯W

7
crossDomain不需要。这是常规jsonp请求,用于跨域通信。
hitautodestruct 2012年

50
我收到相同的错误,但我想发布请求。jsonp将不支持POST。我该如何解决?
iamjustcoder

7
您还将方法从POST更改为GET
Dave Baghdanov

5
@rubdottocom如果url返回xml响应而不是json ...怎么办?
开发人员咨询台

43

我有完全相同的问题,它不是跨域的,而是相同的域。我只是将此行添加到正在处理ajax请求的php文件中。

<?php header('Access-Control-Allow-Origin: *'); ?>

它就像一种魅力。多亏了海报


29
这是非常不安全的。如果有人设法将javascript注入您的页面,他们可以轻松地“回拨”用户可能提供的任何信息。
dclowd9901 2014年

@ dclowd9901:“不安全”是相对的,具体取决于使用目的和观察到的将Access-Control-Allow-Origin标头设置匿名的措施。
nyedidikeke

6

如果在尝试使用服务时遇到此错误,您无法Access-Control-Allow-Origin *在该应用程序中添加标头,但是可以在服务器前放置反向代理,则可以通过重写标头来避免该错误。

假设应用程序在端口8080(公共域位于www.mydomain.com)上运行,并且您将反向代理放在端口80的同一主机上,这是Nginx反向代理的配置:

server {
    listen      80;
    server_name www.mydomain.com;
    access_log  /var/log/nginx/www.mydomain.com.access.log;
    error_log   /var/log/nginx/www.mydomain.com.error.log;

    location / {
        proxy_pass   http://127.0.0.1:8080;
        add_header   Access-Control-Allow-Origin *;
    }   
}

2
如上所述,使用'*'是非常不安全的。
Adaddinsane

5
是的,但是取决于您要暴露的内容。如果您在未经授权的情况下发布公共API,就是这种方式(我的情况)。如果没有,则应使用这样的东西:Access-Control-Allow-Origin: http://example.com
马里亚诺·鲁伊斯

2
当我通过邮递员和ajax测试api时。但是邮递员的要求是成功的。但是在ajax中返回false。
阿拉夫(Araf)

@Araf邮递员和其他应用程序不会触发浏览器内置的CORS保护。
SenseiHitokiri

6

是的,当jQuery看到URL属于另一个域时,它会将该调用假定为跨域调用,因此 crossdomain:true此处不需要。

另外,请务必注意,您无法使用 $.ajax如果您的URL属于另一个域(跨域)或您正在使用JSONP。仅允许异步调用。

注意:如果您在async:false请求中指定,则可以同步调用该服务。


0

就我而言,子域名引起了问题。这是细节

我使用过app_development.something.com,在这里underscore(_)子域正在创建CORS错误。更改app_developmentapp-development正常后。


0

php有一点技巧。它不仅适用于Google,而且适用于您无法控制且无法添加Access-Control-Allow-Origin的任何网站*

我们需要在我们的网络服务器上创建PHP文件(例如getContentFromUrl.php),并做一些技巧。

的PHP

<?php

$ext_url = $_POST['ext_url'];

echo file_get_contents($ext_url);

?>

JS

$.ajax({
    method: 'POST',
    url: 'getContentFromUrl.php', // link to your PHP file
    data: {
        // url where our server will send request which can't be done by AJAX
        'ext_url': '/programming/6114436/access-control-allow-origin-error-sending-a-jquery-post-to-google-apis'
    },
    success: function(data) {
        // we can find any data on external url, cause we've got all page
        var $h1 = $(data).find('h1').html();

        $('h1').val($h1);
    },
    error:function() {
        console.log('Error');
    }
});

这个怎么运作:

  1. 您的浏览器将在JS的帮助下将请求发送到您的服务器
  2. 您的服务器将向其他任何服务器发送请求,并从其他服务器(任何网站)获得回复
  3. 您的服务器会将此回复发送给您的JS

我们可以使事件onClick,将此事件放在某个按钮上。希望这会有所帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.