jQuery AJAX cross domain

Tu są dwie strony, test.php i 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);
?>

Teraz mój problem: gdy oba te pliki są na tym samym serwerze (albo localhost lub web server), to działa i alert("Success") jest wywoływany; jeśli jest na różnych serwerach, czyli testserver.php na serwerze WWW i test.php na localhost, jego nie działa i alert("Error") jest wykonywany. Nawet jeśli adres URL w Ajaxie zostanie zmieniony na http://domain.com/path/to/file/testserver.php

Author: fibono, 2010-08-17

14 answers

Użyj 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).");";
?>
Echo może się mylić, dawno nie używałem php. W każdym przypadku musisz wypisać callbackName('jsonString') zwróć uwagę na cudzysłowy. jQuery przekaże własną nazwę wywołania zwrotnego, więc musisz ją pobrać z GET params.

I jak pisał Stefan Kendall, $.getJSON () jest metodą stenograficzną, ale następnie musisz dołączyć 'callback=?' do adresu url jako parametr GET (tak, wartość jest?, jQuery zastępuje to własnym wygenerowana metoda callback).

 395
Author: BGerrissen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-07 01:26:47

JSONP jest dobrym rozwiązaniem, ale jest łatwiejszy sposób. Możesz po prostu ustawić nagłówek Access-Control-Allow-Origin na swoim serwerze. Ustawienie go na * będzie akceptować żądania AJAX z dowolnej domeny. ( https://developer.mozilla.org/en/http_access_control )

Metoda, aby to zrobić, będzie się różnić w zależności od języka, oczywiście. Tutaj jest w Rails:

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

W tym przykładzie akcja say_hello przyjmie żądania AJAX z dowolnej domeny i zwróci odpowiedź " hello!".

Tutaj jest przykładem nagłówków, które może zwrócić:

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

To proste, ale ma pewne ograniczenia przeglądarki. Zobacz http://caniuse.com/#feat=cors .

 195
Author: joshuarh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-14 16:27:25

Możesz kontrolować to za pomocą nagłówka HTTP, dodając Access-Control-Allow-Origin. Ustawienie go na * będzie akceptować żądania AJAX między domenami z dowolnej domeny.

Korzystanie z PHP jest naprawdę proste, wystarczy dodać następujący wiersz do skryptu, do którego chcesz mieć dostęp poza domeną:

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

Nie zapomnij włączyć modułu mod_headers w httpd.conf.

 28
Author: Adorjan Princz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-14 15:04:03

Musisz przyjrzeć się Tej Samej Polityce Pochodzenia :

W informatyce ta sama polityka pochodzenia jest ważną koncepcją bezpieczeństwa dla Liczba programów po stronie przeglądarki języków, takich jak JavaScript. Na Zasady zezwalają na uruchamianie skryptów na strony pochodzące z tej samej strony dostępu do swoich metod i właściwości bez szczególnych ograniczeń, ale uniemożliwia dostęp do większość metod i właściwości w całym strony w tematyce różne miejsca.

Aby móc uzyskać dane, musi to być:

Ten sam protokół i host

Aby go obejść, musisz zaimplementować JSONP.
 19
Author: Sarfraz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-23 21:09:21

Musiałem załadować stronę z dysku lokalnego " file: / / / C: / test / htmlpage.html", call "http://localhost/getxml.PHP " url, i zrobić to w przeglądarkach IE8+ i Firefox12+, użyj jQuery v1.7. 2 lib, aby zminimalizować kod boilerplate. Po przeczytaniu kilkudziesięciu artykułów w końcu się zorientowałem. Oto moje podsumowanie.

  • server script (.php,jsp,..) musi zwrócić nagłówek odpowiedzi http Access-Control-Allow-Origin: *
  • przed użyciem jQuery ajax ustaw tę flagę w javascript: jQuery.wsparcie.Kors = true;
  • możesz ustawić flagę raz lub za każdym razem przed użyciem funkcji jQuery ajax
  • Teraz mogę czytać .dokument xml w IE i Firefoksie. Innych przeglądarek nie testowałem.
  • dokument odpowiedzi może być zwykły / tekst, xml, json lub cokolwiek innego

Oto przykładowe wywołanie jQuery ajax z niektórymi sysoutami debugowania.

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);
    }
});
 16
Author: Whome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-16 12:34:37

Prawdą jest, że polityka tego samego pochodzenia uniemożliwia JavaScript wysyłanie żądań między domenami, ale specyfikacja CORS pozwala tylko na taki rodzaj dostępu API, którego szukasz i jest obsługiwana przez bieżącą partię głównych przeglądarek.

Zobacz jak włączyć współdzielenie zasobów między źródłami dla klienta i serwera:

Http://enable-cors.org/

"Cross-Origin Resource Sharing (CORS) to specyfikacja, która umożliwia prawdziwie otwarty dostęp ponad granicami domen. Jeśli udostępniasz treści publiczne, rozważ użycie CORS, aby otworzyć je dla uniwersalnego dostępu do JavaScript/przeglądarki."

 10
Author: Jason,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-29 11:09:47

Jest to możliwe, ale musisz użyć JSONP, a nie JSON. Połączenie Stefana wskazało ci właściwy kierunek. Strona jQuery AJAX zawiera więcej informacji na temat JSONP.

Remy Sharp ma szczegółowy przykład użycia PHP.

 9
Author: Paul Schreiber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-17 19:44:07

Używam serwera Apache, więc użyłem modułu mod_proxy. Włącz Moduły:

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

Następnie dodaj:

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

Na koniec przekaż adres URL serwera proxy do skryptu.

 9
Author: zenio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-02 11:58:07

Zabezpieczenia przeglądarki uniemożliwiają wywołanie ajax ze strony hostowanej w jednej domenie do strony hostowanej w innej domenie; nazywa się to "same-origin policy".

 8
Author: Jacob Mattison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-17 20:43:07

Istnieje kilka przykładów użycia JSONP, które obejmują obsługę błędów.

Należy jednak pamiętać, że zdarzenie błędu nie jest wyzwalane podczas korzystania z JSONP! Zobacz: http://api.jquery.com/jQuery.ajax/ lub jQuery AJAX request using JSONP error

 5
Author: BillyTom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:46

Z linku jQuery docs ():

  • Ze względu na ograniczenia bezpieczeństwa przeglądarki, większość żądań "Ajax" podlega tej samej polityce pochodzenia; żądanie nie może pomyślnie pobrać danych z innej domeny, subdomeny lub protokołu.

  • Żądania Script i JSONP nie podlegają tym samym ograniczeniom dotyczącym zasad pochodzenia.

Więc uznałbym, że musisz użyć jsonp do żądania. Ale sam tego nie próbowałem.

 4
Author: William Clemens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-17 19:43:33

Znam 3 sposoby na rozwiązanie twojego problemu:

  1. Najpierw, jeśli masz dostęp do obu domen, możesz zezwolić na dostęp dla wszystkich innych domen za pomocą :

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

    Lub po prostu domenę dodając poniższy kod do .plik htaccess:

    <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. Możesz mieć żądanie ajax do pliku php na serwerze i obsługiwać żądanie do innej domeny za pomocą tego pliku php.

  3. możesz używać jsonp, ponieważ nie wymaga on uprawnień. w tym celu możesz przeczytać nasze przyjaciel @ BGerrissen odpowiedz.
 1
Author: Ali_Hr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-03 12:25:43

W przypadku Microsoft Azure jest to nieco inne rozwiązanie.

Platforma Azure ma specjalne ustawienie CORS, które należy ustawić. Zasadniczo to samo za kulisami, ale samo ustawienie nagłówka nie zadziała. Dokumentacja usługi Azure do włączania różnych domen znajduje się tutaj:

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

Bawiłem się tym kilka godzin przed zdając sobie sprawę, że moja platforma hostingowa miała to specjalne ustawienie.

 0
Author: Josh Schultz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-24 15:02:53

To działa, wszystko czego potrzebujesz:

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 }
});
 0
Author: Paun Narcis Iulian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-04 08:53:19