Access-Control-Allow-Origin – localhost

Tengo problemas para recibir json a través de ajax, el error está debajo. De acuerdo con la información que he encontrado hasta ahora sobre el error, esto parece ser una especie de problema de dominio cruzado, pero no tengo idea de lo que eso significa y cómo resolverlo.

Puede haber un problema con el encabezado de respuesta (yo mismo he creado la API y no tengo experiencias desde antes), sin embargo, se recibe un 200 OK si se accede a la URL directamente desde el navegador.

Si se muestra acceso a la url directamente en el navegador, se muestra json válido, por lo que no debería ser el problema.

¿Cómo se puede resolver esto?

Nota: la url va a un servidor Apache, no a un archivo que haya sido el caso del 95% de las preguntas aquí en la stack que he leído sobre el problema.

Error en el inspector:

XMLHttpRequest cannot load http://localhost/api/v1/products?_=1355583847077. Origin null is not allowed by Access-Control-Allow-Origin. Error: error 

El código:

  $.ajaxSetup ({ url: "http://localhost/api/v1/products", // <--- returns valid json if accessed in the browser type: "GET", dataType: "json", cache: false, contentType: "application/json" }) $.ajax({ success: function(data){ console.log("You made it!"); }, error: function(xhr) { console.log("Error: " + xhr.statusText); } }).done(function(data){ console.log(data); }) 

Parámetros

_ 1355583610778

Encabezados

Cabeceras de respuesta:

 Connection Keep-Alive Content-Length 3887 Content-Type application/json Date Sat, 15 Dec 2012 14:50:53 GMT Keep-Alive timeout=5, max=100 Server Apache/2.2.14 (Unix) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l PHP/5.3.1 mod_perl/2.0.4 Perl/v5.10.1 X-Powered-By PHP/5.3.1 

Encabezados de solicitud:

 Accept application/json, text/javascript, */*; q=0.01 Accept-Encoding gzip, deflate Accept-Language sv-SE,sv;q=0.8,en-US;q=0.5,en;q=0.3 Connection keep-alive Host localhost Origin null User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:17.0) Gecko/17.0 Firefox/17.0 

Respuesta

Nada aquí…

Probar e implementar alguna forma de mecanismo JSONP . Si estás usando PHP, podría ser algo tan simple como esto …

 /* If a callback has been supplied then prepare to parse the callback ** function call back to browser along with JSON. */ $jsonp = false; if ( isset( $_GET[ 'callback' ] ) ) { $_GET[ 'callback' ] = strip_tags( $_GET[ 'callback' ] ); $jsonp = true; $pre = $_GET[ 'callback' ] . '('; $post = ');'; } //isset( $_GET[ 'callback' ] ) /* Encode JSON, and if jsonp is true, then ouput with the callback ** function; if not - just output JSON. */ $json = json_encode( /* data here */ ); print( ( $jsonp ) ? $pre . $json . $post : $json ); 

Todo lo que haría sería buscar una $_GET llamada callback , y luego envolver la salida en una llamada de función, tomando el nombre $_GET['callback'] como un nombre de función.

Entonces tu llamada AJAX se convierte en algo así …

 $.ajax({ type: 'GET', url: '/* script here */ ', data: /* data here - if any */, contentType: "jsonp", // Pay attention to the dataType/contentType dataType: 'jsonp', // Pay attention to the dataType/contentType success: function (json) { /* call back */ } }); 

Cuando a jQuery se le 'jsonp' como dataType / contentType, se encargará de proporcionarle un nombre de función de callback, y configurar la función de callback, etc. lo que significa que no tienes que hacer nada realmente!

De la documentación de jQuery:

“jsonp”: se carga en un bloque JSON utilizando JSONP. Agrega un extra “? Callback =?” hasta el final de su URL para especificar la callback. Deshabilita el almacenamiento en caché agregando un parámetro de cadena de consulta, “_ = [TIMESTAMP]”, a la URL a menos que la opción de caché esté establecida en verdadero.

Fuente

Para concluir; JSONP será su mejor apuesta: he incluido el código PHP en la remota posibilidad de que el script del lado del servidor esté usando PHP; Si no, entonces los principios son los mismos. Sin embargo, las cosas relacionadas con jQuery / client se mantienen igual independientemente de las tecnologías del lado del servidor. ( en general )

Buena suerte 🙂

Sí, este es definitivamente un problema de dominio cruzado. Pero no se preocupe, hay dos soluciones a este problema.

Usando JSONP

Puede implementar el soporte para JSONP (JSON con relleno) en el servidor (es decir, la solución de Fergus Morrow ). JSONP funciona fuera de la caja entre dominios y es básicamente JSON rellenado con una llamada de función.

En su .ajaxSetup establezca dataType en jsonp y luego, en el lado del servidor, asegúrese de verificar un parámetro url denominado callback en la solicitud. Si ese parámetro está establecido, la respuesta JSON debe rellenarse en consecuencia.

 parseThis({ "json": "can", "be": "put", "in": "here" }); 

Lo anterior supone que la callback está configurada para parseThis . jQuery generará por defecto un nombre de función, pero puede anularlo configurando el valor de jsonpCallback en su .ajaxSetup .

También puede usar un atajo para decirle a jQuery que está solicitando JSONP simplemente agregando ?callback=? a la url de solicitud.

Usando Access-Control-Allow-Origin

Una solución alternativa es establecer el encabezado de Access-Control-Allow-Origin en su respuesta.

 Access-Control-Allow-Origin: * 

Lo anterior permitirá que cualquier recurso utilice el dominio cruzado del servicio. Lea el artículo vinculado a continuación para obtener más información sobre cómo configurar Access-Control-Allow .


Si desea obtener más información sobre Access-Control-Origin y CORS, le recomiendo este artículo en MDN .

Lo resolví de una manera muy fácil, agregando el siguiente encabezado a mi código de servidor (php):

 header('Access-Control-Allow-Origin: *'); 

Si se trata de una aplicación WEB de ASP.NET, también puede poner esto en su Global.aspx:

HttpContext.Current.Response.AddHeader (“Access-Control-Allow-Origin”, “*”);

Más configuraciones de encabezado de PHP

 header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Methods: POST, GET, OPTIONS'); header('Access-Control-Max-Age: 1000'); header('Access-Control-Allow-Headers: Content-Type'); 

Buena suerte