jQuery.getJSON – Problema di Access-Control-Allow-Origin

Sto giustificando la funzione $.getJSON() jQuery per restituire un breve insieme di dati JSON.

Ho i dati JSON su un URL come example.com . Non me ne sono reso conto, ma mentre stavo accedendo a quello stesso url, i dati JSON non potevano essere caricati. Ho seguito la console e ho scoperto che XMLHttpRequest non poteva essere caricato a causa di Access-Control-Allow-Origin .

Ora ho letto un sacco di siti che hanno appena detto di usare $.getJSON() e che sarebbe stato il problema, ma ovviamente non ha funzionato. C’è qualcosa che dovrei cambiare nelle intestazioni o nella funzione?

L’aiuto è molto apprezzato.

È semplice, usa la funzione $.getJSON() e includi solo l’URL

callback =?

come parametro Ciò convertirà la chiamata a JSONP, necessaria per effettuare chiamate tra domini. Maggiori informazioni: http://api.jquery.com/jQuery.getJSON/

Potresti voler usare JSON-P invece (vedi sotto). Prima una rapida spiegazione.

L’intestazione che hai citato proviene dallo standard Cross Origin Resource Sharing . Attenzione che non è supportato da alcuni browser che le persone effettivamente usano, e su altri browser (Microsoft, sigh ) richiede l’uso di un object speciale ( XDomainRequest ) piuttosto che la richiesta XDomainRequest standard richiesta da jQuery. È inoltre necessario modificare le risorse sul lato server per consentire esplicitamente l’altra origine ( www.xxxx.com ).

Per ottenere i dati JSON che stai richiedendo, in pratica hai tre opzioni:

  1. Se ansible, puoi essere massimamente compatibile correggendo la posizione dei file che stai caricando in modo che abbiano la stessa origine del documento in cui li stai caricando. (Suppongo che tu stia caricandoli tramite Ajax, quindi il problema della stessa politica di origine si presenta.)

  2. Usa JSON-P , che non è sobject al SOP. jQuery ha il supporto integrato per la sua chiamata ajax (basta impostare dataType su “jsonp” e jQuery eseguirà tutto il lavoro lato client). Ciò richiede modifiche lato server, ma non molto grandi; in pratica qualunque cosa tu stia generando la risposta JSON cerca solo un parametro stringa di query chiamato “callback” e avvolge il JSON nel codice JavaScript che chiamerebbe quella funzione. Ad esempio, se la tua attuale risposta JSON è:

     {"weather": "Dreary start but soon brightening into a fine summer day."} 

    Lo script cercherà il parametro della stringa di query “callback” (diciamo che il valore del parametro è “jsop123”) e avvolge tale JSON nella syntax per una chiamata di funzione JavaScript:

     jsonp123({"weather": "Dreary start but soon brightening into a fine summer day."}); 

    Questo è tutto. JSON-P è molto compatibile (perché funziona tramite tag script JavaScript). JSON-P è solo per GET , però, non POST (di nuovo perché funziona tramite tag script ).

  3. Usa CORS (il meccanismo relativo all’intestazione che hai citato). Dettagli nella specifica collegati sopra , ma fondamentalmente:

    A. Il browser invierà al server un messaggio di “preflight” utilizzando il verbo HTTP (metodo) OPTIONS . Conterrà le varie intestazioni che invierà con GET o POST così come le intestazioni “Origin”, “Access-Control-Request-Method” (ad esempio, GET o POST ) e “Access-Control-Request-Headers” (le intestazioni che vuole inviare).

    B. Il tuo php decide, in base a tali informazioni, se la richiesta è accettabile e in caso affermativo risponde con “Access-Control-Allow-Origin”, “Access-Control-Allow-Methods” e “Access-Control-Allow- Intestazioni “intestazioni con i valori consentiti. Non si invia alcun corpo (pagina) con quella risposta.

    C. Il browser guarderà la tua risposta e vedrà se è permesso inviarti il GET o POST effettivo. Se è così, invierà quella richiesta, ancora con le intestazioni “Origin” e varie “Access-Control-Request-xyz”.

    D. Il tuo PHP esamina nuovamente quelle intestazioni per assicurarsi che siano ancora a posto, e in tal caso risponde alla richiesta.

    In pseudo -code (non ho fatto molto PHP, quindi non sto cercando di fare la syntax PHP qui):

     // 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 

    Sottolineando ancora che si tratta di pseudo-codice.