Erreur Access-Control-Allow-Origin lors de l'envoi d'une publication jQuery aux API Google

143

J'ai beaucoup lu pour l'erreur 'Access-Control-Allow-Origin', mais je ne comprends pas ce que je dois corriger :(

Je joue avec l'API Google Moderator, mais lorsque j'essaie d' ajouter une nouvelle série, je reçois:

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.

J'ai essayé avec et sans paramètre de rappel, j'ai essayé d'ajouter 'Access-Control-Allow-Origin *' à l'en-tête. Et je ne sais pas comment utiliser $ .getJSON ici, si cela s'applique, car je dois ajouter l'en-tête Authorization et je ne sais pas comment le faire sans beforeCall de $ .ajax: /

Une lumière pour cette obscurité uu?

C'est le 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
la source
1
pourriez-vous s'il vous plaît mettre votre code un peu plus complètement? Je n'ai pas pu exécuter votre code.
Hosein Aqajani

Réponses:

249

J'ai résolu l'erreur Access-Control-Allow-Origin en modifiant le paramètre dataType en dataType: 'jsonp' et en ajoutant un 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
});
rubdottocom
la source
20
Je ne pense pas que ce crossDomain:truesoit nécessaire. Je crois comprendre que cela n'est nécessaire que si vous faites une demande sur votre propre domaine mais que vous souhaitez que jQuery la traite comme une demande inter-domaines.
Alex W
7
crossDomainn'est pas nécessaire. il s'agit d'une jsonpdemande régulière destinée à une communication interdomaine.
hitautodestruct
50
J'obtiens la même erreur, mais je souhaite publier la demande. jsonp ne prend pas en charge POST. Comment puis-je résoudre ce problème?
iamjustcoder
7
Vous avez également changé votre méthode de POST à ​​GET
Dave Baghdanov
5
@rubdottocom et si url renvoie une réponse xml au lieu de json ...?
Developer Desk
43

J'ai eu exactement le même problème et ce n'était pas un domaine croisé mais le même domaine. Je viens d'ajouter cette ligne au fichier php qui traitait la requête ajax.

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

Ça a marché comme sur des roulettes. Merci à l'affiche

Muhammad Tanweer
la source
29
Ceci est très dangereux. Si quelqu'un parvient à injecter du javascript dans votre page, il pourrait facilement "téléphoner à la maison" toute information qu'un utilisateur pourrait fournir.
dclowd9901
@ dclowd9901: "Unsafe" est relatif selon le but de l'utilisation et les mesures observées pour définir l'en -tête Access-Control-Allow-Origin sur anonyme entre autres raisons.
nyedidikeke
6

Si vous rencontrez cette erreur en essayant de consommer un service dont vous ne pouvez pas ajouter l'en-tête Access-Control-Allow-Origin *dans cette application, mais que vous pouvez placer un proxy inverse devant le serveur, l'erreur peut être évitée avec une réécriture d'en-tête.

En supposant que l'application fonctionne sur le port 8080 (domaine public sur www.mondomaine.com ) et que vous placez le proxy inverse dans le même hôte au port 80, voici la configuration du proxy inverse 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 *;
    }   
}
Mariano Ruiz
la source
2
Comme mentionné ci-dessus, l'utilisation de «*» est très dangereuse.
Adaddinsane
5
Oui, mais en fonction de ce que vous exposez. Si vous publiez une API publique sans autorisation, c'est comme ça (mon cas). Si ne aimez pas, vous qui devraient être utiliser somethig ceci: Access-Control-Allow-Origin: http://example.com.
Mariano Ruiz
2
quand je teste une API via Postman et Ajax. mais la demande du facteur est un succès. mais en ajax retourne false.
Araf
@Araf postman et d'autres applications ne déclenchent pas les protections CORS intégrées aux navigateurs.
SenseiHitokiri
6

Oui, au moment où jQuery voit que l'URL appartient à un domaine différent, il suppose que l'appel est un appel interdomaine, donc crossdomain:truen'est pas nécessaire ici.

De plus, il est important de noter que vous ne pouvez pas passer un appel synchrone avec $.ajax si votre URL appartient à un domaine différent (domaine croisé) ou si vous utilisez JSONP. Seuls les appels asynchrones sont autorisés.

Remarque: vous pouvez appeler le service de manière synchrone si vous spécifiez le async:falseavec votre demande.

Vivek Jain
la source
0

Dans mon cas, le sous-nom de domaine pose problème. Voici les détails

J'ai utilisé app_development.something.com, ici le _sous-domaine underscore ( ) crée une erreur CORS. Après avoir changé app_developmentà app-developmentcela fonctionne très bien.

Zéro
la source
0

Il y a un petit hack avec php. Et cela fonctionne non seulement avec Google, mais avec tout site Web que vous ne contrôlez pas et ne pouvez pas ajouter Access-Control-Allow-Origin *

Nous devons créer un fichier PHP (ex. GetContentFromUrl.php ) sur notre serveur Web et faire une petite astuce.

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

Comment ça fonctionne:

  1. Votre navigateur avec l'aide de JS enverra une demande à votre serveur
  2. Votre serveur enverra une demande à n'importe quel autre serveur et obtiendra une réponse d'un autre serveur (n'importe quel site Web)
  3. Votre serveur enverra cette réponse à votre JS

Et nous pouvons créer des événements onClick, mettre cet événement sur un bouton. J'espère que cela aidera!

dfox
la source