jQuery AJAX cross-domein

Hier zijn twee pagina’s, test.php en testserver.php.

test.php

<script src="scripts/jq.js" type="text/javascript"></script>
<script>
    $(function() {
        $.ajax({url:"testserver.php",
            success:function() {
                alert("Success");
            },
            error:function() {
                alert("Error");
            },
            dataType:"json",
            type:"get"
        }
    )})
</script>

testserver.php

<?php
$arr = array("element1",
             "element2",
             array("element31","element32"));
$arr['name'] = "response";
echo json_encode($arr);
?>

Nu mijn probleem: wanneer beide bestanden op dezelfde server staan (ofwel localhost of webserver), werkt het en wordt alert("Success")aangeroepen; Als het op verschillende servers staat, dus testserver.php op de webserver en test.php op localhost, werkt het niet en wordt alert("Error")uitgevoerd. Zelfs als de URL binnen ajax wordt gewijzigd in http://domain.com/path/to/ file/testserver.php


Antwoord 1, autoriteit 100%

Gebruik JSONP.

jQuery:

$.ajax({
     url:"testserver.php",
     dataType: 'jsonp', // Notice! JSONP <-- P (lowercase)
     success:function(json){
         // do stuff with json (in this case an array)
         alert("Success");
     },
     error:function(){
         alert("Error");
     }      
});

PHP:

<?php
$arr = array("element1","element2",array("element31","element32"));
$arr['name'] = "response";
echo $_GET['callback']."(".json_encode($arr).");";
?>

De echo kan verkeerd zijn, het is een tijdje geleden dat ik php heb gebruikt. In ieder geval moet u callbackName('jsonString')uitvoeren en let op de aanhalingstekens. jQuery geeft zijn eigen callback-naam door, dus je moet die uit de GET-parameters halen.

En zoals Stefan Kendall heeft gepost, is $.getJSON()een verkorte methode, maar dan moet je 'callback=?'aan de url toevoegen als GET-parameter (ja, waarde is ?, jQuery vervangt dit door zijn eigen gegenereerde callback-methode).


Antwoord 2, autoriteit 50%

JSONP is een goede optie, maar er is een eenvoudigere manier. U kunt eenvoudig de Access-Control-Allow-Origin-header op uw server instellen. Als u dit instelt op *, accepteert u AJAX-verzoeken voor meerdere domeinen van elk domein. (https://developer.mozilla.org/en/http_access_control)

De methode om dit te doen verschilt natuurlijk van taal tot taal. Hier is het in Rails:

class HelloController < ApplicationController
  def say_hello
    headers['Access-Control-Allow-Origin'] = "*"
    render text: "hello!"
  end
end

In dit voorbeeld accepteert de actie say_helloAJAX-verzoeken van elk domein en retourneert een reactie van “hello!”.

Hier is een voorbeeld van de headers die het kan retourneren:

HTTP/1.1 200 OK 
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: text/html; charset=utf-8
X-Ua-Compatible: IE=Edge
Etag: "c4ca4238a0b923820dcc509a6f75849b"
X-Runtime: 0.913606
Content-Length: 6
Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
Date: Thu, 01 Mar 2012 20:44:28 GMT
Connection: Keep-Alive

Hoe eenvoudig het ook is, het heeft wel enkele browserbeperkingen. Zie http://caniuse.com/#feat=cors.


Antwoord 3, autoriteit 8%

Je kunt dit regelen via de HTTP-header door Access-Control-Allow-Origintoe te voegen. Als u dit instelt op *, accepteert u AJAX-verzoeken van verschillende domeinen van elk domein.

Het gebruik van PHPis heel eenvoudig, voeg gewoon de volgende regel toe aan het script waartoe u toegang wilt hebben buiten uw domein:

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

Vergeet niet om mod_headers module in httpd.conf in te schakelen.


Antwoord 4, autoriteit 5%

Je moet eens kijken naar Same Origin Policy:

In computergebruik hetzelfde oorsprongsbeleid
is een belangrijk veiligheidsconcept voor een
aantal browser-side programmering
talen, zoals JavaScript. De
beleid staat scripts toe die worden uitgevoerd op
pagina’s afkomstig van dezelfde site
om toegang te krijgen tot elkaars methoden en
eigenschappen zonder specifieke
beperkingen, maar verhindert toegang tot
de meeste methoden en eigenschappen over
pagina’s op verschillende sites.

Om gegevens te kunnen krijgen, moet dit het volgende zijn:

Zelfde protocol en host

Je moet JSONPimplementeren om dit te omzeilen.


Antwoord 5, Autoriteit 4%

Ik moest webpagina laden van lokaal schijf “Bestand: /// C: /test/htmlpage.html”, bel “http: //localhost/getxml.php” URL, en doe dit in IE8 + en Firefox12 + browsers, Gebruik jQuery v1.7.2 lib om boilerplatecode te minimaliseren. Na het lezen van tientallen artikelen dacht uiteindelijk het uit. Hier is mijn samenvatting.

  • Server-script (.php, .jsp, …) MOET HTTP-responskoptoegangscontrole-toestaan-oorsprong retourneren: *
  • Voordat u JQuery Ajax gebruikt, zet deze vlag in JavaScript: jQuery.support.cors = TRUE;
  • U kunt een of telkens vlag instellen voordat u JQuery Ajax-functie gebruikt
  • Nu kan ik .xml-document in IE en Firefox lezen. Andere browsers die ik niet heb getest.
  • Respons-document kan eenvoudig / tekst, XML, JSON of iets anders zijn

Hier is een voorbeeld JQuery Ajax-oproep met enkele foutopsporingen.

jQuery.support.cors = true;
$.ajax({
    url: "http://localhost/getxml.php",
    data: { "id":"doc1", "rows":"100" },
    type: "GET",
    timeout: 30000,
    dataType: "text", // "xml", "json"
    success: function(data) {
        // show text reply as-is (debug)
        alert(data);
        // show xml field values (debug)
        //alert( $(data).find("title").text() );
        // loop JSON array (debug)
        //var str="";
        //$.each(data.items, function(i,item) {
        //  str += item.title + "\n";
        //});
        //alert(str);
    },
    error: function(jqXHR, textStatus, ex) {
        alert(textStatus + "," + ex + "," + jqXHR.responseText);
    }
});

Antwoord 6, Autoriteit 2%

Het is waar dat hetzelfde-oorsprongbeleid verhindert dat JavaScript verzoeken doet in verschillende domeinen, maar de CORS-specificatie biedt precies het soort API-toegang dat u zoekt en wordt ondersteund door de huidige reeks grote browsers.

Bekijk hoe u het delen van bronnen tussen verschillende bronnen inschakelt voor client en server:

http://enable-cors.org/

“Cross-Origin Resource Sharing (CORS) is een specificatie die echt open toegang mogelijk maakt over domeingrenzen heen. Als je openbare inhoud aanbiedt, overweeg dan om CORS te gebruiken om het open te stellen voor universele JavaScript-/browsertoegang.”


Antwoord 7, autoriteit 2%

Dit is mogelijk, maar u moet JSONP gebruiken, niet JSON. Stefan’s link wees je in de goede richting. De jQuery AJAX-paginabevat meer informatie over JSONP.

Remy Sharp heeft een gedetailleerd voorbeeld met PHP.


Antwoord 8, autoriteit 2%

Ik gebruik de Apache-server, dus ik heb de mod_proxy-module gebruikt. Modules inschakelen:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

Voeg dan toe:

ProxyPass /your-proxy-url/ http://service-url:serviceport/

Geef ten slotte de proxy-url door aan uw script.


Antwoord 9, autoriteit 2%

Browserbeveiliging voorkomt dat een ajax-aanroep wordt gedaan vanaf een pagina die wordt gehost op het ene domein naar een pagina die wordt gehost op een ander domein; dit wordt het “same-origin-beleid” genoemd.


Antwoord 10

Er zijn weinig voorbeelden voor het gebruik van JSONP, waaronder foutafhandeling.

Houd er echter rekening mee dat de foutgebeurtenis niet wordt geactiveerd bij gebruik van JSONP! Zie: http://api.jquery.com/jQuery.ajax/of jQuery ajax-verzoek met jsonp-fout


Antwoord 11

Van de JQuery-documenten (link):

  • Vanwege browserbeveiligingsbeperkingen zijn de meeste “Ajax”-verzoeken onderworpen aan hetzelfde oorsprongsbeleid; het verzoek kan geen gegevens ophalen van een ander domein, subdomein of protocol.

  • Script- en JSONP-verzoeken zijn niet onderworpen aan dezelfde beperkingen van het oorsprongsbeleid.

Dus ik neem aan dat je jsonp moet gebruiken voor het verzoek. Maar heb dit zelf niet geprobeerd.


Antwoord 12

Ik weet drie manieren om uw probleem op te lossen:

  1. Als u toegang heeft tot beide domeinen, kunt u toegang verlenen aan alle andere domeinen met :

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

    of gewoon een domein door onderstaande code toe te voegen aan het .htaccess-bestand:

    <FilesMatch "\.(ttf|otf|eot|woff)$">
    <IfModule mod_headers.c>
    SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.net|dev02.otherdomain.net)$" AccessControlAllowOrigin=$0
    Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    </IfModule>
    </FilesMatch>

  2. je kunt een ajax-verzoek naar een php-bestand op je server hebben en een verzoek naar een ander domein afhandelen met dit php-bestand.

  3. je kunt jsonp gebruiken, omdat het geen toestemming nodig heeft. hiervoor kun je het antwoord van onze vriend @BGerrissen lezen.

Antwoord 13

Voor Microsoft Azure is het iets anders.

Azure heeft een speciale CORS-instelling die moet worden ingesteld. Het is in wezen hetzelfde achter de schermen, maar het simpelweg instellen van de header die Joshuarh noemt zal niet werken. De Azure-documentatie voor het inschakelen van domeinoverstijgend is hier te vinden:

https ://docs.microsoft.com/en-us/azure/app-service-api/app-service-api-cors-consume-javascript

Ik heb hier een paar uur mee zitten spelen voordat ik me realiseerde dat mijn hostingplatform deze speciale instelling had.


Antwoord 14

het werkt, alles wat je nodig hebt:

PHP:

header('Access-Control-Allow-Origin: http://www.example.com');
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');

JS (jQuery ajax):

var getWBody = $.ajax({ cache: false,
        url: URL,
        dataType : 'json',
        type: 'GET',
        xhrFields: { withCredentials: true }
});

Other episodes