Error de acceso-control-permitir-origen al enviar una publicación jQuery a las API de Google

143

Leí mucho sobre el error 'Access-Control-Allow-Origin', pero no entiendo lo que tengo que arreglar :(

Estoy jugando con la API de Google Moderator, pero cuando intento agregar una nueva serie recibo:

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.

Intenté con y sin parámetro de devolución de llamada, intenté agregar 'Access-Control-Allow-Origin *' al encabezado. Y no sé cómo usar $ .getJSON aquí, si corresponde, porque tengo que agregar el encabezado de autorización y no sé cómo hacerlo sin beforeCall desde $ .ajax: /

¿Alguna luz para esta oscuridad uu?

Ese es el código:

<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
fuente
1
¿podría por favor poner su código un poco más completamente? No pude ejecutar tu código.
Hosein Aqajani

Respuestas:

249

Resolví el error de Access-Control-Allow-Origin modificando el parámetro dataType a dataType: 'jsonp' y agregando 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
fuente
20
No creo que crossDomain:truese requiera. Tengo entendido que solo es necesario si realiza una solicitud en su propio dominio pero desea que jQuery lo trate como una solicitud de dominio cruzado.
Alex W
77
crossDomainno es necesario. Esta es una jsonpsolicitud regular destinada a la comunicación entre dominios.
hitautodestruct
50
Recibo el mismo error, pero quiero publicar la solicitud. jsonp no admitirá POST. ¿Cómo puedo resolver esto?
iamjustcoder
77
También cambiaste tu método de POST a GET
Dave Baghdanov el
55
@rubdottocom ¿y si url devuelve una respuesta xml en lugar de json ...?
Escritorio del desarrollador el
43

Tuve exactamente el mismo problema y no era dominio cruzado sino el mismo dominio. Acabo de agregar esta línea al archivo php que manejaba la solicitud ajax.

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

Funcionó a las mil maravillas. Gracias al cartel

Muhammad Tanweer
fuente
29
Esto es muy inseguro. Si alguien logra inyectar JavaScript en su página, podría "llamar a casa" fácilmente cualquier información que un usuario pueda proporcionar.
dclowd9901
@ dclowd9901: "Inseguro" es relativo según el propósito de uso y las medidas observadas para establecer el encabezado Access-Control-Allow-Origin en anónimo, entre otras razones.
nyedidikeke
6

Si tiene este error al tratar de consumir un servicio que no puede agregar el encabezado Access-Control-Allow-Origin *en esa aplicación, pero puede colocar frente al servidor un proxy inverso, el error puede evitarse con una reescritura del encabezado.

Suponiendo que la aplicación se está ejecutando en el puerto 8080 (dominio público en www.midominio.com ), y coloca el proxy inverso en el mismo host en el puerto 80, esta es la configuración para el proxy inverso de 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
fuente
2
Como se mencionó anteriormente, usar '*' es muy inseguro.
Adaddinsane
55
Sí, pero dependiendo de lo que expongas. Si está publicando una API pública sin autorización, esa es la forma (mi caso). Si no lo hace, pues, deben utilización somethig como esto: Access-Control-Allow-Origin: http://example.com.
Mariano Ruiz
2
cuando pruebo una API a través de cartero y ajax. pero la solicitud del cartero es un éxito. pero en ajax devuelve falso.
Araf
@Araf cartero y otras aplicaciones no activan las protecciones CORS integradas en los navegadores.
SenseiHitokiri
6

Sí, en el momento en que jQuery ve que la URL pertenece a un dominio diferente, asume esa llamada como una llamada de dominio cruzado, por lo tanto, crossdomain:trueno se requiere aquí.

Además, es importante tener en cuenta que no puede realizar una llamada sincrónica $.ajaxsi su URL pertenece a un dominio diferente (dominio cruzado) o si está utilizando JSONP. Solo se permiten llamadas asíncronas.

Nota: puede llamar al servicio sincrónicamente si especifica el async:falsecon su solicitud.

Vivek Jain
fuente
0

En mi caso, el nombre de subdominio causa el problema. Aquí hay detalles

Solía app_development.something.com, aquí el _subdominio subrayado ( ) está creando un error CORS. Después de cambiar app_developmenta app-developmentfunciona bien.

Cero
fuente
0

Hay un pequeño truco con php. Y funciona no solo con Google, sino con cualquier sitio web que no controle y no pueda agregar Access-Control-Allow-Origin *

Necesitamos crear un archivo PHP (ej. GetContentFromUrl.php ) en nuestro servidor web y hacer un pequeño truco.

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

Cómo funciona:

  1. Su navegador con la ayuda de JS enviará una solicitud a su servidor
  2. Su servidor enviará una solicitud a cualquier otro servidor y recibirá respuesta de otro servidor (cualquier sitio web)
  3. Su servidor enviará esta respuesta a su JS

Y podemos hacer eventos en Click, poner este evento en algún botón. Espero que esto ayude!

dfox
fuente