2010-04-23 12 views
98

¿Es posible publicar datos en JsonP? ¿O todos los datos tienen que pasar en la cadena de consulta como una solicitud GET?Publicar datos en JsonP

Tengo un montón de datos que tengo que enviar al servicio, dominios, y es demasiado grande para enviar a través de la cadena de consulta

¿Cuáles son las opciones para conseguir alrededor de esto?

Respuesta

81

No es posible hacer una POST asincrónica a un servicio en otro dominio, debido a la limitación (bastante sensible) de same origin policy. JSON-P solo funciona porque tiene permitido insertar etiquetas <script> en el DOM, y pueden apuntar a cualquier lugar.

Puede, por supuesto, hacer una página en otro dominio la acción de un formulario regular POST.

Editar: Hay algunas interesting hacks hacia fuera allí si usted está dispuesto a ir a una gran cantidad de esfuerzo de inserción ocultos s y curioseaba con sus propiedades.

+0

Mencionó que un "POST asíncrono" no es posible ... ¿entonces puedo hacer un POST síncrono? – Mark

+4

@mark "POST sincrónico" significa enviar un formulario que utiliza

+8

Esto no es del todo cierto.Ciertamente puedes hacer solicitudes 'POST' a otros dominios siempre que tanto ese dominio como tu navegador admitan' CORS'. Pero es totalmente cierto que 'POST' y' JSONP' no son compatibles. – hippietrail

4

En general, JSONP se implementa agregando una etiqueta <script> al documento que hace la llamada, de modo que la URL del servicio JSONP es "src". El navegador obtiene el origen del script con una transacción HTTP GET.

Ahora, si su servicio JSONP está en el mismo dominio que su página de llamada, entonces probablemente podría improvisar algo junto con una simple llamada $.ajax(). Si no está en el mismo dominio, entonces no estoy seguro de cómo sería posible.

+0

No está en el mismo dominio en este caso. Y asumo que solo GET es posible, pero quería comprobar que solo he comenzado a leer sobre JsonP hoy y necesito tomar algunas decisiones sobre si es adecuado para lo que necesito – ChrisCa

+2

Si no está en el mismo dominio pero admite 'CORS', entonces será posible siempre que el navegador también lo admita. En estos casos, utilizará 'JSON' simple en lugar de' JSONP'. – hippietrail

+0

Sí, @hippietrail 2 años hace una gran diferencia :-) CORS definitivamente lo hace posible, pero por supuesto requiere que la fuente de datos se configure correctamente. – Pointy

17

Si necesita enviar una gran cantidad de datos entre dominios. Por lo general, creo un servicio al que puede llamar en dos pasos:

  1. Primero, el cliente debe enviar un FORMATO (la publicación permite el dominio cruzado). El servicio almacena la entrada en la sesión en el servidor (usando el GUID como clave). (el cliente crea un GUID y lo envía como parte de la entrada)

  2. Luego el cliente realiza un script-inject normal (JSONP) como parámetro utiliza el mismo GUID que utilizó en la publicación FORM. El servicio procesa la entrada de la sesión y devuelve los datos en la forma JSONP normal. Después de esto, la sesión se destruye.

Esto, por supuesto, se basa en que se escribe el servidor-backend.

+1

Probé su enfoque. Trabajó para FF14 y Chrome20. Opera11 e IE9 simplemente no transfirieron la publicación. (Lo revisó con sus herramientas de depuración y escuchó en el servidor en el otro extremo) Tal vez en relación con la discapacidad del IE es esta pregunta: http://stackoverflow.com/questions/10395803/cross-domain-post-request-ajax-in -internet-explorer Queja de Chrome en la consola, pero aún así la POST: XMLHttpRequest no puede cargar http: // localhost: 8080/xxx Origen nulo no está permitido por Access-Control-Allow-Origin. – OneWorld

+0

@OneWorld - No hiciste lo que decía la respuesta. 'XMLHttpRequest' no debería estar involucrado en absoluto. La respuesta de Per utiliza un envío de formulario regular para realizar la solicitud POST, luego una inyección de elemento de script para realizar la solicitud GET. – Quentin

-6

Es posible, aquí está mi solución:

En su javascript:

jQuery.post("url.php",data).complete(function(data) { 
    eval(data.responseText.trim()); 
}); 
function handleRequest(data){ 
    .... 
} 

En su url.php:

echo "handleRequest(".$responseData.")"; 
+11

En este caso, jQuery probablemente convirtió su solicitud en Obtener de acuerdo con su documentación: Nota: Esto convertirá las POST en GET para las solicitudes de dominio remoto. http://api.jquery.com/jQuery.ajax/ – OneWorld

-1

Hay una (truco) solución que he lo hizo muchas veces, podrá Publicar con JsonP. (Usted será capaz de publicar de forma, más grande que 2000 carbón que se puede utilizar por GET) Aplicación cliente

Javascript

$.ajax({ 
    type: "POST", // you request will be a post request 
    data: postData, // javascript object with all my params 
    url: COMAPIURL, // my backoffice comunication api url 
    dataType: "jsonp", // datatype can be json or jsonp 
    success: function(result){ 
    console.dir(result); 
    } 
}); 

JAVA:

response.addHeader("Access-Control-Allow-Origin", "*"); // open your api to any client 
response.addHeader("Access-Control-Allow-Methods", "POST"); // a allow post 
response.addHeader("Access-Control-Max-Age", "1000"); // time from request to response before timeout 

PHP:

header('Access-Control-Allow-Origin: *'); 
header('Access-Control-Allow-Methods: POST'); 
header('Access-Control-Max-Age: 1000'); 

Al hacer esto, está abriendo su servidor a cualquier solicitud posterior, debe volver a proteger esto proporcionando ident u otra cosa.

Con este método, también se puede cambiar el tipo de solicitud de jsonp a JSON, tanto en el trabajo, acaba de establecer la respuesta correcta tipo de contenido

jsonp

response.setContentType("text/javascript; charset=utf-8"); 

JSON

response.setContentType("application/json; charset=utf-8"); 

Por favor, no se que su servidor ya no respetará el SOP (mismo orig en política), pero ¿a quién le importa?

+0

Esto no es AJAX con CORS. AJAX implica que estás usando XML. Esto es JSON [P] con CORS. JSONP es "JSON" con "Padding". Si está enviando datos JSON, envuelto con una llamada de función para relleno, entonces es JSONP con CORS. Puedes usar las notaciones de datos JSON y JSONP fuera de solo insertar las etiquetas '