Access-Control-Allow-Origin-Fehler beim Senden eines jQuery-Posts an Google-APIs

143

Ich habe viel für den Fehler 'Access-Control-Allow-Origin' gelesen, aber ich verstehe nicht, was ich beheben muss :(

Ich spiele mit der Google Moderator-API, aber wenn ich versuche, eine neue Serie hinzuzufügen, erhalte ich:

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.

Ich habe versucht, mit und ohne Rückrufparameter 'Access-Control-Allow-Origin *' zum Header hinzuzufügen. Und ich weiß nicht, wie ich $ .getJSON hier verwenden soll, wenn zutreffend, weil ich den Authorization-Header hinzufügen muss und nicht weiß, wie ich es ohne beforeCall von $ .ajax machen soll: /

Irgendein Licht für diese Dunkelheit?

Das ist der Code:

<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 -->
rubdottocom
quelle
1
Könnten Sie bitte Ihren Code etwas vollständiger eingeben? Ich konnte Ihren Code nicht ausführen.
Hosein Aqajani

Antworten:

249

Ich habe den Fehler Access-Control-Allow-Origin behoben, indem ich den Parameter dataType in dataType: 'jsonp' geändert und eine crossDomain: true hinzugefügt habe

$.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
});
rubdottocom
quelle
20
Ich denke nicht, dass das crossDomain:trueerforderlich ist. Nach meinem Verständnis ist dies nur erforderlich, wenn Sie eine Anfrage in Ihrer eigenen Domain stellen, aber möchten, dass jQuery sie wie eine domänenübergreifende Anfrage behandelt.
Alex W
7
crossDomainwird nicht gebraucht. Dies ist eine reguläre jsonpAnfrage, die für die domänenübergreifende Kommunikation gedacht ist.
Hitautodestruct
50
Ich erhalte den gleichen Fehler, aber ich möchte die Anfrage posten. jsonp unterstützt POST nicht. Wie kann ich das lösen?
iamjustcoder
7
Sie haben auch Ihre Methode von POST auf GET geändert
Dave Baghdanov
5
@rubdottocom Was ist, wenn die URL eine XML-Antwort anstelle von JSON zurückgibt?
Developer Desk
43

Ich hatte genau das gleiche Problem und es war nicht domänenübergreifend, sondern dieselbe Domäne. Ich habe diese Zeile gerade zu der PHP-Datei hinzugefügt, die die Ajax-Anfrage bearbeitet hat.

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

Es funktionierte wie ein Zauber. Danke an das Plakat

Muhammad Tanweer
quelle
29
Das ist sehr unsicher. Wenn es jemandem gelingt, Javascript in Ihre Seite einzufügen, kann er alle Informationen, die ein Benutzer möglicherweise bereitstellt, problemlos "nach Hause telefonieren".
dclowd9901
@ dclowd9901: "Unsicher" ist relativ, abhängig vom Verwendungszweck und den Maßnahmen, die zum Setzen des Headers "Access-Control-Allow-Origin" unter anderem auf anonym gesetzt wurden.
Nyedidikeke
6

Wenn dieser Fehler beim Versuch auftritt, einen Dienst zu nutzen, bei dem Sie den Header Access-Control-Allow-Origin *in dieser Anwendung nicht hinzufügen können, Sie jedoch einen Reverse-Proxy vor den Server stellen können, kann der Fehler durch ein Umschreiben des Headers vermieden werden.

Angenommen, die Anwendung wird auf Port 8080 (gemeinfrei unter www.mydomain.com ) ausgeführt und Sie setzen den Reverse-Proxy auf demselben Host an Port 80, ist dies die Konfiguration für den Nginx- Reverse-Proxy:

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 *;
    }   
}
Mariano Ruiz
quelle
2
Wie oben erwähnt, ist die Verwendung von '*' sehr unsicher.
Adaddinsane
5
Ja, aber je nachdem, was Sie aussetzen. Wenn Sie eine öffentliche API ohne Autorisierung veröffentlichen, ist dies der Fall (mein Fall). Wenn nicht, sollten Sie so etwas verwenden : Access-Control-Allow-Origin: http://example.com.
Mariano Ruiz
2
wenn ich eine API durch Postbote und Ajax teste. Aber Postbotenanfragen sind Erfolg. aber in ajax return false.
Araf
@Araf Postbote und andere Anwendungen lösen keine CORS-Schutzfunktionen aus, die in Browsern integriert sind.
SenseiHitokiri
6

Ja, sobald jQuery sieht, dass die URL zu einer anderen Domain gehört, wird davon ausgegangen, dass der Anruf ein domänenübergreifender Anruf ist und daher crossdomain:truehier nicht erforderlich ist.

Beachten Sie außerdem, dass Sie keinen synchronen Anruf tätigen können, $.ajaxwenn Ihre URL zu einer anderen Domäne (domänenübergreifend) gehört oder Sie JSONP verwenden. Es sind nur asynchrone Anrufe zulässig.

Hinweis: Sie können den Dienst synchron aufrufen, wenn Sie dies async:falsemit Ihrer Anfrage angeben .

Vivek Jain
quelle
0

In meinem Fall verursacht der Subdomainname das Problem. Hier sind Details

Ich habe verwendet app_development.something.com, hier _erzeugt die Unterdomäne underscore ( ) einen CORS-Fehler. Nach dem Wechsel app_developmentauf app-developmentes funktioniert gut.

Null
quelle
0

Es gibt einen kleinen Hack mit PHP. Und es funktioniert nicht nur mit Google, sondern mit jeder Website, die Sie nicht kontrollieren und die Access-Control-Allow-Origin * nicht hinzufügen kann.

Wir müssen eine PHP-Datei (zB getContentFromUrl.php ) auf unserem Webserver erstellen und einen kleinen Trick machen.

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');
    }
});

Wie es funktioniert:

  1. Ihr Browser sendet mit Hilfe von JS eine Anfrage an Ihren Server
  2. Ihr Server sendet eine Anfrage an einen anderen Server und erhält eine Antwort von einem anderen Server (einer beliebigen Website).
  3. Ihr Server sendet diese Antwort an Ihren JS

Und wir können Ereignisse auf Klick machen, dieses Ereignis auf eine Schaltfläche setzen. Hoffe das wird helfen!

dfox
quelle