Use JSON-P, que no está sujeto al SOP. jQuery tiene soporte integrado en su llamada ajax
(simplemente configure dataType
en "jsonp" y jQuery hará todo el trabajo del lado del cliente). Esto requiere cambios en el servidor, pero no muy grandes; básicamente, cualquier cosa que tenga que genere la respuesta JSON solo busca un parámetro de cadena de consulta llamado "devolución de llamada" y ajusta el JSON en código JavaScript que llamaría a esa función. Por ejemplo, si su respuesta JSON actual es:
{"weather": "Dreary start but soon brightening into a fine summer day."}
Su guión se vería para el parámetro de cadena de consulta "callback" (digamos que el valor del parámetro es "jsop123") y envuelve que JSON en la sintaxis de una JavaScript llamada de función:
jsonp123({"weather": "Dreary start but soon brightening into a fine summer day."});
Eso es todo. JSON-P es muy ampliamente compatible (porque funciona a través de las etiquetas JavaScript script
). JSON-P es solo para GET
, sin embargo, no POST
(una vez más porque funciona a través de las etiquetas script
).
Utilice CORS (el mecanismo relacionado con el encabezado que citó). Detalles en the specification linked above, pero básicamente:
A. El navegador enviará a su servidor un mensaje "Preflight" utilizando el OPTIONS
verbo HTTP (método).Contendrá los distintos encabezados que enviaría con GET
o POST
, así como los encabezados "Origen", "Método de solicitud de control de acceso" (p. Ej., GET
o POST
) y "Cabeceras de solicitud de control de acceso". (los encabezados que quiere enviar).
B. Su PHP decide, basándose en esa información, si la solicitud es correcta y si responde con "Access-Control-Allow-Origin", "Access-Control-Allow-Methods" y "Access- Encabezados Control-Allow-Headers "con los valores que permitirá. No envía ningún cuerpo (página) con esa respuesta.
C. El navegador examinará su respuesta y verá si se le permite enviar el GET
o POST
. Si es así, enviará esa solicitud, nuevamente con el "Origen" y varios encabezados "Access-Control-Request-xyz".
D. Su PHP examina esos encabezados nuevamente para asegurarse de que siguen estando bien, y en caso afirmativo responde a la solicitud.
En seudo -code (no he hecho mucho de PHP, así que no estoy tratando de hacer aquí sintaxis de PHP):
// Find out what the request is asking for
corsOrigin = get_request_header("Origin")
corsMethod = get_request_header("Access-Control-Request-Method")
corsHeaders = get_request_header("Access-Control-Request-Headers")
if corsOrigin is null or "null" {
// Requests from a `file://` path seem to come through without an
// origin or with "null" (literally) as the origin.
// In my case, for testing, I wanted to allow those and so I output
// "*", but you may want to go another way.
corsOrigin = "*"
}
// Decide whether to accept that request with those headers
// If so:
// Respond with headers saying what's allowed (here we're just echoing what they
// asked for, except we may be using "*" [all] instead of the actual origin for
// the "Access-Control-Allow-Origin" one)
set_response_header("Access-Control-Allow-Origin", corsOrigin)
set_response_header("Access-Control-Allow-Methods", corsMethod)
set_response_header("Access-Control-Allow-Headers", corsHeaders)
if the HTTP request method is "OPTIONS" {
// Done, no body in response to OPTIONS
stop
}
// Process the GET or POST here; output the body of the response
De nuevo haciendo hincapié en que se trata de pseudo-código.
Quizás le interese consultar JSONP: http://en.wikipedia.org/wiki/JSONP. – pimvdb
Una alternativa sería reenviar su solicitud y respuesta utilizando un proxy (por ejemplo, PHP curl) si eso está disponible para usted. – Dan