【问题标题】:Access-Control-Allow-Origin error sending a jQuery Post to Google API's将 jQuery Post 发送到 Google API 的 Access-Control-Allow-Origin 错误
【发布时间】:2011-09-01 03:33:51
【问题描述】:

我阅读了很多关于“Access-Control-Allow-Origin”错误的内容,但我不明白我必须修复什么:(

我正在使用 Google Moderator API,但当我尝试 add new serie 时,我收到:

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

【问题讨论】:

  • 你能把你的代码更完整一点吗?我无法运行您的代码。

标签: jquery ajax google-api cors jsonp


【解决方案1】:

试试我的代码 在 JavaScript 中

 var settings = {
              "url": "https://myinboxhub.co.in/example",
              "method": "GET",
              "timeout": 0,
              "headers": {},
            };
        $.ajax(settings).done(function (response) {
          console.log(response);
            if (response.auth) { 
                console.log('on success');
            } 
        }).fail(function (jqXHR, exception) { 
                var msg = '';
                if (jqXHR.status === '(failed)net::ERR_INTERNET_DISCONNECTED') {
                    
                        msg = 'Uncaught Error.\n' + jqXHR.responseText; 
                }
                if (jqXHR.status === 0) {
                        msg = 'Not connect.\n Verify Network.';
                } else if (jqXHR.status == 413) {
                        msg = 'Image size is too large.'; 
                }  else if (jqXHR.status == 404) {
                        msg = 'Requested page not found. [404]'; 
                } else if (jqXHR.status == 405) {
                        msg = 'Image size is too large.'; 
                } else if (jqXHR.status == 500) {
                        msg = 'Internal Server Error [500].'; 
                } else if (exception === 'parsererror') {
                        msg = 'Requested JSON parse failed.'; 
                } else if (exception === 'timeout') {
                        msg = 'Time out error.'; 
                } else if (exception === 'abort') {
                        msg = 'Ajax request aborted.'; 
                } else {
                        msg = 'Uncaught Error.\n' + jqXHR.responseText; 
                }
                console.log(msg);
        });;

在 PHP 中

header('Content-type: application/json');
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET");
header("Access-Control-Allow-Methods: GET, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Content-Length, Accept-Encoding");

【讨论】:

    【解决方案2】:

    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': 'https://stackoverflow.com/questions/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

    我们可以在点击事件上进行事件,把这个事件放在某个按钮上。 希望这会有所帮助!

    【讨论】:

      【解决方案3】:

      在我的情况下,子域名会导致问题。以下是详细信息

      我使用app_development.something.com,这里下划线(_)子域正在创建CORS错误。将app_development 更改为app-development 后,它工作正常。

      【讨论】:

        【解决方案4】:

        是的,当 jQuery 看到 URL 属于不同的域时,它假定调用是跨域调用,因此这里不需要crossdomain:true

        另外,需要注意的是,如果您的 URL 属于不同的域(跨域)或者您使用的是 JSONP,则无法使用 $.ajax 进行同步调用。只允许异步调用。

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

        【讨论】:

          【解决方案5】:

          如果您在尝试使用无法在该应用程序中添加标头 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 *;
              }   
          }
          

          【讨论】:

          • 如上所述使用'*'是非常不安全的。
          • 是的,但取决于您要公开的内容。如果您在未经授权的情况下发布公共 API,那就是这样(我的情况)。如果不这样做,你应该使用这样的东西:Access-Control-Allow-Origin: http://example.com
          • 当我通过邮递员和 ajax 测试 api 时。但邮递员的要求是成功的。但在 ajax 中返回 false。
          • @Araf postman 和其他应用程序不会触发浏览器内置的 CORS 保护。
          【解决方案6】:

          我遇到了完全相同的问题,不是跨域而是同一个域。我刚刚将这一行添加到处理 ajax 请求的 php 文件中。

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

          它就像一个魅力。感谢发帖者

          【讨论】:

          • 这是非常不安全的。如果有人设法将 javascript 注入您的页面,他们可以轻松地“打电话回家”用户可能提供的任何信息。
          • @dclowd9901: "Unsafe" 是相对的,具体取决于使用目的和设置 Access-Control-Allow-Origin 标头所观察到的措施除了其他原因,匿名
          【解决方案7】:

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

          $.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
          });
          

          【讨论】:

          • 我不认为crossDomain:true 是必需的。我的理解是,仅当您在自己的域上发出请求但希望 jQuery 将其视为跨域请求时才需要。
          • crossDomain 不是必需的。这是一个常规的jsonp 请求,用于跨域通信。
          • 我收到同样的错误,但我想发布请求。 jsonp 将不支持 POST。我该如何解决这个问题?
          • 您还将方法从 POST 更改为 GET
          • @rubdottocom 如果 url 返回 xml 响应而不是 json...?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-12-09
          • 1970-01-01
          • 2018-03-16
          • 2021-03-17
          • 2013-05-08
          • 2012-05-08
          相关资源
          最近更新 更多