Đang tải điểm cuối tên miền chéo với AJAX


131

Tôi đang cố tải trang HTML tên miền chéo bằng AJAX nhưng trừ khi DataType là "jsonp", tôi không thể nhận được phản hồi. Tuy nhiên, bằng cách sử dụng jsonp, trình duyệt đang mong đợi một loại kịch bản kịch bản nhưng đang nhận được "văn bản / html".

Mã của tôi cho yêu cầu là:

$.ajax({
    type: "GET",
    url: "http://saskatchewan.univ-ubs.fr:8080/SASStoredProcess/do?_username=DARTIES3-2012&_password=P@ssw0rd&_program=%2FUtilisateurs%2FDARTIES3-2012%2FMon+dossier%2Fanalyse_dc&annee=2012&ind=V&_action=execute",
    dataType: "jsonp",
}).success( function( data ) {
    $( 'div.ajax-field' ).html( data );
});

Có cách nào để tránh sử dụng jsonp cho yêu cầu không? Tôi đã thử sử dụng tham số crossDomain nhưng nó không hoạt động.

Nếu không có cách nào để nhận nội dung html trong jsonp? Hiện tại giao diện điều khiển đang nói "không mong đợi <" trong phản hồi jsonp.


Tôi đã giải quyết vấn đề bằng cách tạo proxy.php như được giải thích ở đây scode7.blogspot.com/2019/11/NH
CodeDezk

Câu trả lời:


235

Ghi chú jQuery jQuery

  • Do các hạn chế bảo mật của trình duyệt, hầu hết các yêu cầu Ajax đều phải tuân theo cùng một chính sách xuất xứ ; yêu cầu không thể truy xuất thành công dữ liệu từ một tên miền, tên miền phụ, cổng hoặc giao thức khác nhau.
  • Các yêu cầu Script và JSONP không bị hạn chế chính sách gốc.

Có một số cách để vượt qua rào cản tên miền chéo :

Có một số plugin giúp yêu cầu tên miền chéo :

Đứng lên!

Cách tốt nhất để khắc phục vấn đề này là bằng cách tạo proxy của riêng bạn ở back-end, để proxy của bạn sẽ trỏ đến các dịch vụ trong các miền khác, bởi vì trong back-end không tồn tại cùng một hạn chế chính sách gốc . Nhưng nếu bạn không thể làm điều đó trong back-end, thì hãy chú ý đến các mẹo sau.


Cảnh báo!

Sử dụng proxy của bên thứ ba không phải là một cách an toàn, bởi vì họ có thể theo dõi dữ liệu của bạn, vì vậy nó có thể được sử dụng với thông tin công khai, nhưng không bao giờ với dữ liệu riêng tư.


Các ví dụ mã được hiển thị bên dưới sử dụng jQuery.get ()jQuery.getJSON () , cả hai đều là các phương thức tốc ký của jQuery.ajax ()


CORS bất cứ nơi nào

CORS Anywhere là proxy node.js bổ sung các tiêu đề CORS vào yêu cầu ủy quyền.
Để sử dụng API, chỉ cần thêm tiền tố URL với URL API. (Hỗ trợ https : xem kho lưu trữ github )

Nếu bạn muốn tự động kích hoạt các yêu cầu tên miền chéo khi cần, hãy sử dụng đoạn mã sau:

$.ajaxPrefilter( function (options) {
  if (options.crossDomain && jQuery.support.cors) {
    var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');
    options.url = http + '//cors-anywhere.herokuapp.com/' + options.url;
    //options.url = "http://cors.corsproxy.io/url=" + options.url;
  }
});

$.get(
    'http://en.wikipedia.org/wiki/Cross-origin_resource_sharing',
    function (response) {
        console.log("> ", response);
        $("#viewer").html(response);
});


Dù xuất xứ gì

Bất cứ nguồn gốc nào là truy cập jsonp tên miền chéo . Đây là một nguồn mở thay thế cho anyorigin.com .

Để tìm nạp dữ liệu từ google.com, bạn có thể sử dụng đoạn mã này:

// It is good specify the charset you expect.
// You can use the charset you want instead of utf-8.
// See details for scriptCharset and contentType options: 
// http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
$.ajaxSetup({
    scriptCharset: "utf-8", //or "ISO-8859-1"
    contentType: "application/json; charset=utf-8"
});

$.getJSON('http://whateverorigin.org/get?url=' + 
    encodeURIComponent('http://google.com') + '&callback=?',
    function (data) {
        console.log("> ", data);

        //If the expected response is text/plain
        $("#viewer").html(data.contents);

        //If the expected response is JSON
        //var response = $.parseJSON(data.contents);
});


Proxy CORS

CORS Proxy là một proxy node.js đơn giản để kích hoạt yêu cầu CORS cho bất kỳ trang web nào. Nó cho phép mã javascript trên trang web của bạn truy cập tài nguyên trên các tên miền khác thường bị chặn do chính sách cùng nguồn gốc.

Làm thế nào nó hoạt động? CORS Proxy tận dụng Chia sẻ tài nguyên nguồn gốc chéo, đây là một tính năng được thêm vào cùng với HTML 5. Máy chủ có thể chỉ định rằng họ muốn trình duyệt cho phép các trang web khác yêu cầu tài nguyên mà họ lưu trữ. CORS Proxy chỉ đơn giản là một Proxy HTTP có thêm tiêu đề cho các phản hồi với nội dung "bất kỳ ai cũng có thể yêu cầu điều này".

Đây là một cách khác để đạt được mục tiêu (xem www.corsproxy.com ). Tất cả bạn phải làm là dải http: //www. từ URL được ủy quyền và thêm URL vớiwww.corsproxy.com/

$.get(
    'http://www.corsproxy.com/' +
    'en.wikipedia.org/wiki/Cross-origin_resource_sharing',
    function (response) {
        console.log("> ", response);
        $("#viewer").html(response);
});


Trình duyệt proxy CORS

Gần đây tôi tìm thấy cái này, nó liên quan đến các tiện ích Chia sẻ từ xa theo định hướng bảo mật khác nhau. Nhưng nó là một hộp đen với Flash là phụ trợ.

Bạn có thể thấy nó hoạt động ở đây: Trình duyệt proxy CORS
Lấy mã nguồn trên GitHub: koto / cors-proxy-browser


4
Bạn cũng có thể triển khai phiên bản
AnyOrigin.org

1
Hình ảnh, CSS và javascript bên ngoài có thể được tham chiếu từ một nguồn gốc khác, do đó, trong phản hồi, bạn có thể đi qua chuỗi HTML và thay thế src của các tài nguyên bên ngoài
jherax

1
hi jherax Tôi đã sử dụng anyorigin để có được một trang html (cách duy nhất làm việc cho tôi, sử dụng yql, google, v.v.) nhưng các ký tự không phải tiếng Anh là lạ. đã cố mã hóa data.contents nhưng không được giúp đỡ
user217648

1
Xin chào @Miru, như tiêu đề nói: "Đang tải trang html tên miền chéo bằng jQuery AJAX", tôi đã trả lời tiêu đề bằng cách cung cấp một số ví dụ sử dụng proxy để thực hiện các yêu cầu tên miền chéo. Ngoài ra, để trả lời cho từ ngữ của câu hỏi, tôi đã cung cấp một số liên kết để thực hiện các yêu cầu tên miền chéo bằng JSONP với YQL. Tôi mời bạn đọc các liên kết, chúng rất hữu ích.
jherax

1
Đã kết thúc bằng phương pháp CORS Anywhere với $.ajaxPrefiltervà nó hoạt động rất tốt. Cảm ơn nhiều!
Joshua Pinter

24

Bạn có thể sử dụng Ajax-cross-origin một plugin jQuery. Với plugin này, bạn sử dụng jQuery.ajax()tên miền chéo. Nó sử dụng các dịch vụ của Google để đạt được điều này:

Plugin AJAX Cross Origin sử dụng Google Apps Script làm proxy json getter nơi jSONP không được triển khai. Khi bạn đặt tùy chọn crossOrigin thành true, plugin sẽ thay thế url gốc bằng địa chỉ Google Apps Script và gửi dưới dạng tham số url được mã hóa. Tập lệnh Google Apps sử dụng tài nguyên Máy chủ Google để lấy dữ liệu từ xa và trả lại cho khách hàng dưới dạng JSONP.

Nó rất đơn giản để sử dụng:

    $.ajax({
        crossOrigin: true,
        url: url,
        success: function(data) {
            console.log(data);
        }
    });

Bạn có thể đọc thêm tại đây: http://www.ajax-cross-origin.com/


21
Theo như tôi biết, plugin này chưa bao giờ hoạt động. Nó không làm gì trên Chrome.
Michael

Làm thế nào tôi có thể xác thực với máy chủ?
sttaq

làm việc tuyệt vời API tôi đang sử dụng không hỗ trợ JSONP hay CORS, vì vậy đây là điều duy nhất hoạt động. Cảm ơn rất nhiều!
JP Lew

crossOriginTùy chọn của jQuery chắc chắn không làm gì để giảm thiểu các chính sách cùng nguồn gốc. Tôi sẽ xóa câu trả lời này nếu tôi có thể
Phil

13

Nếu trang bên ngoài không hỗ trợ JSONP hoặc CORS, tùy chọn duy nhất của bạn là sử dụng proxy.

Xây dựng tập lệnh trên máy chủ của bạn yêu cầu nội dung đó, sau đó sử dụng jQuery ajax để nhấn tập lệnh trên máy chủ của bạn.


5

Chỉ cần đặt cái này vào tiêu đề của Trang PHP của bạn và nó không hoạt động nếu không có API:

header('Access-Control-Allow-Origin: *'); //allow everybody  

hoặc là

header('Access-Control-Allow-Origin: http://codesheet.org'); //allow just one domain 

hoặc là

$http_origin = $_SERVER['HTTP_ORIGIN'];  //allow multiple domains

$allowed_domains = array(
  'http://codesheet.org',
  'http://stackoverflow.com'
);

if (in_array($http_origin, $allowed_domains))
{  
    header("Access-Control-Allow-Origin: $http_origin");
}

Tôi đang tự hỏi từ đâu $_SERVER['HTTP_ORIGIN']đến. Tôi không thể tìm thấy nó trong tài liệu PHP hoặc bất cứ nơi nào khác.
Zsolti

Hmm, có vẻ như nó chỉ được điền với các yêu cầu AJAX. Nhưng dù sao, cảm ơn câu trả lời.
Zsolti

0

Tôi đang đăng bài này trong trường hợp ai đó phải đối mặt với cùng một vấn đề mà tôi đang phải đối mặt ngay bây giờ. Tôi đã có một máy in nhiệt Zebra, được trang bị máy chủ in ZebraNet, cung cấp giao diện người dùng dựa trên HTML để chỉnh sửa nhiều cài đặt, xem trạng thái hiện tại của máy in, v.v. Tôi cần phải có trạng thái của máy in, được hiển thị trong một trong những trang html đó, được cung cấp bởi máy chủ ZebraNet và, ví dụ, cảnh báo () một thông báo cho người dùng trong trình duyệt. Điều này có nghĩa là tôi phải lấy trang html đó trước trong Javascript. Mặc dù máy in nằm trong mạng LAN của PC người dùng, Chính sách xuất xứ tương tựvẫn đang vững bước theo cách của tôi. Tôi đã thử JSONP, nhưng máy chủ trả về html và tôi chưa tìm được cách sửa đổi chức năng của nó (nếu có thể, tôi đã đặt tiêu đề ma thuật Access-control-allow-origin: *). Vì vậy, tôi quyết định viết một ứng dụng giao diện điều khiển nhỏ bằng C #. Nó phải được chạy với tư cách là Admin để hoạt động bình thường, nếu không thì nó troll: D là một ngoại lệ. Đây là một số mã:

// Create a listener.
        HttpListener listener = new HttpListener();
        // Add the prefixes.
        //foreach (string s in prefixes)
        //{
        //    listener.Prefixes.Add(s);
        //}
        listener.Prefixes.Add("http://*:1234/"); // accept connections from everywhere,
        //because the printer is accessible only within the LAN (no portforwarding)
        listener.Start();
        Console.WriteLine("Listening...");
        // Note: The GetContext method blocks while waiting for a request. 
        HttpListenerContext context;
        string urlForRequest = "";

        HttpWebRequest requestForPage = null;
        HttpWebResponse responseForPage = null;
        string responseForPageAsString = "";

        while (true)
        {
            context = listener.GetContext();
            HttpListenerRequest request = context.Request;
            urlForRequest = request.RawUrl.Substring(1, request.RawUrl.Length - 1); // remove the slash, which separates the portNumber from the arg sent
            Console.WriteLine(urlForRequest);

            //Request for the html page:
            requestForPage = (HttpWebRequest)WebRequest.Create(urlForRequest);
            responseForPage = (HttpWebResponse)requestForPage.GetResponse();
            responseForPageAsString = new StreamReader(responseForPage.GetResponseStream()).ReadToEnd();

            // Obtain a response object.
            HttpListenerResponse response = context.Response;
            // Send back the response.
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseForPageAsString);
            // Get a response stream and write the response to it.
            response.ContentLength64 = buffer.Length;
            response.AddHeader("Access-Control-Allow-Origin", "*"); // the magic header in action ;-D
            System.IO.Stream output = response.OutputStream;
            output.Write(buffer, 0, buffer.Length);
            // You must close the output stream.
            output.Close();
            //listener.Stop();

Tất cả những gì người dùng cần làm là chạy ứng dụng console đó với tư cách Quản trị viên. Tôi biết đó là cách quá ... bực bội và phức tạp, nhưng nó là một cách giải quyết vấn đề Chính sách miền trong trường hợp bạn không thể sửa đổi máy chủ theo bất kỳ cách nào.

chỉnh sửa: từ js Tôi thực hiện một cuộc gọi ajax đơn giản:

$.ajax({
                type: 'POST',
                url: 'http://LAN_IP:1234/http://google.com',
                success: function (data) {
                    console.log("Success: " + data);
                },
                error: function (e) {
                    alert("Error: " + e);
                    console.log("Error: " + e);
                }
            });

Html của trang được yêu cầu được trả về và được lưu trong biến dữ liệu .


0

Để có được trang web bên ngoài mẫu dữ liệu bằng cách chuyển qua proxy cục bộ như được đề xuất bởi jherax, bạn có thể tạo một trang php tìm nạp nội dung cho bạn từ url bên ngoài tương ứng và gửi yêu cầu đến trang php đó.

var req = new XMLHttpRequest();
req.open('GET', 'http://localhost/get_url_content.php',false);
if(req.status == 200) {
   alert(req.responseText);
}

làm proxy php, bạn có thể sử dụng https://github.com/cowboy/php-simple-proxy


0

Bạn URLkhông làm việc trong những ngày này, nhưng mã của bạn có thể được cập nhật với giải pháp làm việc này:

var url = "http://saskatchewan.univ-ubs.fr:8080/SASStoredProcess/do?_username=DARTIES3-2012&_password=P@ssw0rd&_program=%2FUtilisateurs%2FDARTIES3-2012%2FMon+dossier%2Fanalyse_dc&annee=2012&ind=V&_action=execute";

url = 'https://google.com'; // TEST URL

$.get("https://images"+~~(Math.random()*33)+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=" + encodeURI(url), function(data) {
    $('div.ajax-field').html(data);
});
<div class="ajax-field"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


-2

Bạn cần proxy CORS ủy quyền yêu cầu của bạn từ trình duyệt của bạn đến dịch vụ được yêu cầu với các tiêu đề CORS phù hợp . Danh sách các dịch vụ như vậy nằm trong đoạn mã dưới đây. Bạn cũng có thể chạy đoạn mã được cung cấp để xem ping đến các dịch vụ như vậy từ vị trí của bạn.

$('li').each(function() {
  var self = this;
  ping($(this).text()).then(function(delta) {
    console.log($(self).text(), delta, ' ms');
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/jdfreder/pingjs/c2190a3649759f2bd8569a72ae2b597b2546c871/ping.js"></script>
<ul>
  <li>https://crossorigin.me/</li>
  <li>https://cors-anywhere.herokuapp.com/</li>
  <li>http://cors.io/</li>
  <li>https://cors.5apps.com/?uri=</li>
  <li>http://whateverorigin.org/get?url=</li>
  <li>https://anyorigin.com/get?url=</li>
  <li>http://corsproxy.nodester.com/?src=</li>
  <li>https://jsonp.afeld.me/?url=</li>
  <li>http://benalman.com/code/projects/php-simple-proxy/ba-simple-proxy.php?url=</li>
</ul>


11
Điều này không trả lời câu hỏi theo bất kỳ cách nào.
0xc0de

@ 0xc0de cuối cùng tôi đã viết câu trả lời.
galeksandrp

-7

Tìm ra. Sử dụng điều này thay thế.

$('.div_class').load('http://en.wikipedia.org/wiki/Cross-origin_resource_sharing #toctitle');

Mã bạn đã sử dụng ở đó là không liên quan. Vấn đề là các tiêu đề CORS phía máy chủ.
Quentin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.