2010-04-23 17 views
98

È possibile inviare dati a JsonP? O tutti i dati devono essere passati in querystring come una richiesta GET?Inviare dati a JsonP

Ho un sacco di dati che ho bisogno di inviare al servizio, dominio croce, ed è troppo grande per contattare direttamente via querystring

Quali sono le opzioni per ottenere intorno a questo?

risposta

81

Non è possibile eseguire uno POST asincrono su un servizio su un altro dominio, a causa della (abbastanza ragionevole) limitazione dello same origin policy. JSON-P funziona solo perché ti è permesso inserire i tag <script> nel DOM e possono puntare ovunque.

È possibile, ovviamente, creare una pagina su un altro dominio l'azione di un modulo POST regolare.

Edit: Ci sono alcuni interesting hacks là fuori, se siete disposti ad andare a un sacco di fatica inserire nascosti s e pasticciare in giro con le loro proprietà.

+0

Hai detto che un "POST asincrono" non è possibile .... allora posso fare un POST sincrono? – Mark

+4

@mark "POST sincrono" indica l'invio di un modulo che utilizza

+8

Questo non è del tutto vero.Certamente puoi fare richieste POST ad altri domini fintanto che sia dominio che browser supportano 'CORS'. Ma è assolutamente vero che 'POST' e' JSONP' non sono compatibili. – hippietrail

4

Generalmente, JSONP viene implementato aggiungendo un tag <script> al documento chiamante, in modo tale che l'URL del servizio JSONP sia "src". Il browser recupera l'origine dello script con una transazione HTTP GET.

Ora, se il servizio JSONP si trova nello stesso dominio della pagina chiamante, è probabile che si possa associare qualcosa a una semplice chiamata $.ajax(). Se non si trova nello stesso dominio, non sono sicuro di come sarebbe possibile.

+0

In questo caso non è nello stesso dominio. E presumo che solo GET sia possibile, ma volevo controllare dato che ho iniziato a leggere solo su JsonP oggi e ho bisogno di prendere alcune decisioni sul fatto che sia adatto a quello che mi serve – ChrisCa

+2

Se non è nello stesso dominio ma supporta 'CORS' allora sarà possibile fintanto che il browser lo supporti anche. In questi casi userete semplicemente 'JSON' piuttosto che' JSONP'. – hippietrail

+0

Sì, @hippietrail 2 anni fa una grande differenza :-) CORS rende sicuramente possibile, ma ovviamente richiede che l'origine dei dati sia impostata in modo appropriato. – Pointy

17

Se è necessario inviare molti dati tra domini diversi. Generalmente creo un servizio che è possibile chiamare in due passaggi:

  1. Prima il client invia un FORM (post consentito dominio incrociato). Il servizio memorizza l'input nella sessione sul server (utilizzando il GUID come chiave). (il client crea un GUID e lo invia come parte dell'input)

  2. Quindi il client esegue un normale script-inject (JSONP) come parametro per utilizzare lo stesso GUID utilizzato nel post FORM. Il servizio elabora l'input dalla sessione e restituisce i dati nel normale modo JSONP. Dopo questo la sessione viene distrutta.

Questo ovviamente si basa sul server back-end.

+1

Ho provato il tuo approccio. Ha funzionato per FF14 e Chrome20. Opera11 e IE9 non hanno appena trasferito il post. (Controllato con i loro strumenti di debug e ascoltato sul server dall'altra parte) Forse correlato alla disabilità di IE è questa domanda: http://stackoverflow.com/questions/10395803/cross-domain-post-request-ajax-in -internet-explorer Segnalazione di Chrome nella console, ma ancora il POST: XMLHttpRequest non può caricare http: // localhost: 8080/xxx Origine null non è consentita da Access-Control-Allow-Origin. – OneWorld

+0

@OneWorld - Non hai fatto ciò che la risposta ha detto. 'XMLHttpRequest' non dovrebbe essere coinvolto affatto. La risposta di Per utilizza un invio di moduli regolari per effettuare la richiesta POST, quindi un'iniezione di elementi script per effettuare la richiesta GET. – Quentin

-6

E 'possibile, ecco la mia soluzione:

Nel vostro javascript:

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

Nel vostro url.php:

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

In questo caso jQuery molto probabilmente ha trasformato la tua richiesta in Get in base alla loro documentazione: Nota: questo trasformerà i POST in GET per le richieste di dominio remoto. http://api.jquery.com/jQuery.ajax/ – OneWorld

-1

C'è una soluzione (hack) ho lo ha fatto molte volte, sarete in grado di pubblicare con JsonP. (Sarete in grado di modulo per l'inserimento, più grande di 2000 char che è possibile utilizzare da GET) applicazione client

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

In questo modo, si sta aprendo il server a qualsiasi richiesta di post, è necessario ripristinarlo fornendo identità o qualcos'altro.

Con questo metodo, si potrebbe anche cambiare il tipo di richiesta da jsonp a JSON, sia il lavoro, è sufficiente impostare la risposta giusta tipo di contenuto

jsonp

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

JSON

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

Si prega di notare che il server non rispetterà più SOP (stessa origine nella politica), ma a chi importa?

+0

Questo non è AJAX con CORS. AJAX implica che stai usando XML. Questo è JSON [P] con CORS. JSONP è "JSON" con "Padding". Se sta inviando dati JSON, avvolto con una chiamata di funzione per il padding, allora è JSONP con CORS. Puoi usare entrambe le annotazioni dei dati JSON e JSONP al di fuori della semplice iniezione di '