Memuat titik akhir lintas domain dengan AJAX


131

Saya mencoba memuat halaman HTML lintas domain menggunakan AJAX tetapi kecuali tipe data "jsonp" saya tidak bisa mendapatkan respons. Namun menggunakan jsonp, peramban mengharapkan jenis skrip mime tetapi menerima "teks / html".

Kode saya untuk permintaan adalah:

$.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 );
});

Apakah ada cara untuk menghindari menggunakan jsonp untuk permintaan? Saya sudah mencoba menggunakan parameter crossDomain tetapi tidak berhasil.

Jika tidak, adakah cara untuk menerima konten html di jsonp? Saat ini konsol mengatakan "tak terduga <" ​​di jsonp reply.


Saya telah menyelesaikan masalah dengan membuat proxy.php seperti yang dijelaskan di sini scode7.blogspot.com/2019/11/…
CodeDezk

Jawaban:


235

Catatan jQuery Ajax

  • Karena pembatasan keamanan browser, sebagian besar permintaan Ajax tunduk pada kebijakan asal yang sama ; permintaan tidak dapat berhasil mengambil data dari domain, subdomain, port, atau protokol yang berbeda.
  • Permintaan skrip dan JSONP tidak tunduk pada batasan kebijakan asal yang sama.

Ada beberapa cara untuk mengatasi penghalang lintas-domain :

Ada beberapa plugin yang membantu dengan permintaan lintas-domain :

Kepala!

Cara terbaik untuk mengatasi masalah ini, adalah dengan membuat proxy Anda sendiri di back-end, sehingga proxy Anda akan menunjuk ke layanan di domain lain, karena di back-end tidak ada batasan kebijakan asal yang sama . Tetapi jika Anda tidak bisa melakukan itu di back-end, maka perhatikan tips berikut.


Peringatan!

Menggunakan proxy pihak ketiga bukanlah praktik yang aman, karena mereka dapat melacak data Anda, sehingga dapat digunakan dengan informasi publik, tetapi tidak pernah dengan data pribadi.


Contoh kode yang ditunjukkan di bawah ini menggunakan jQuery.get () dan jQuery.getJSON () , keduanya adalah metode singkatan dari jQuery.ajax ()


CORS Anywhere

CORS Anywhere adalah proxy node.js yang menambahkan header CORS ke permintaan proksi.
Untuk menggunakan API, cukup awali URL dengan URL API. (Mendukung https : lihat repositori github )

Jika Anda ingin secara otomatis mengaktifkan permintaan lintas domain saat diperlukan, gunakan cuplikan berikut:

$.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);
});


Asal apapun

Apapun Asal adalah akses jsonp lintas domain . Ini adalah alternatif sumber terbuka untuk anyorigin.com .

Untuk mengambil data dari google.com, Anda dapat menggunakan potongan ini:

// 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 adalah proxy node.js sederhana untuk mengaktifkan permintaan CORS untuk situs web apa pun. Ini memungkinkan kode javascript di situs Anda untuk mengakses sumber daya di domain lain yang biasanya akan diblokir karena kebijakan asal yang sama.

Bagaimana cara kerjanya? CORS Proxy mengambil keuntungan dari Cross-Origin Resource Sharing, yang merupakan fitur yang ditambahkan bersama dengan HTML 5. Server dapat menentukan bahwa mereka ingin browser mengizinkan situs web lain untuk meminta sumber daya yang dihosting. CORS Proxy hanyalah Proxy HTTP yang menambahkan header ke respons yang mengatakan "siapa pun dapat meminta ini".

Ini adalah cara lain untuk mencapai tujuan (lihat www.corsproxy.com ). Yang harus Anda lakukan adalah menghapus http: // dan www. dari URL yang diproksikan, dan tambahkan URL denganwww.corsproxy.com/

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


Browser proxy CORS

Baru-baru ini saya menemukan yang satu ini, itu melibatkan berbagai utilitas Cross Origin Remote Sharing yang berorientasi keamanan. Tapi itu adalah kotak hitam dengan Flash sebagai backend.

Anda dapat melihatnya beraksi di sini: Browser proxy CORS
Dapatkan kode sumber di GitHub: koto / cors-proxy-browser


4
Anda juga dapat menggunakan versi ANYOrigin.org
Origin

1
Gambar, CSS, dan javascript eksternal dapat dirujuk dari asal lain, dengan demikian, dalam respons Anda dapat memeriksa string HTML dan mengganti src sumber daya eksternal
jherax

1
hai jherax Saya menggunakan apa punigin untuk mendapatkan halaman html (satu-satunya cara bekerja untuk saya, digunakan yql, google dll) tetapi karakter non Inggris yang aneh. mencoba menyandikan data.contents tetapi tidak membantu
user217648

1
Halo @Miru, seperti judulnya: "Memuat halaman html lintas domain dengan jQuery AJAX", saya menjawab judul dengan memberikan beberapa contoh menggunakan proxy untuk melakukan permintaan lintas-domain. Juga, dalam menanggapi kata-kata dari pertanyaan, saya menyediakan beberapa tautan untuk membuat permintaan lintas-domain menggunakan JSONP dengan YQL. Saya mengundang Anda untuk membaca tautannya, mereka sangat berguna.
jherax

1
Akhirnya menggunakan metode CORS Anywhere dengan $.ajaxPrefilterdan itu berhasil. Terimakasih banyak!
Joshua Pinter

24

Anda dapat menggunakan Ajax-cross-origin sebagai plugin jQuery. Dengan plugin ini Anda menggunakan jQuery.ajax()domain silang. Ini menggunakan layanan Google untuk mencapai ini:

Pengaya AJAX Cross Origin menggunakan Google Apps Script sebagai proksi pengambil jSON proksi di mana jSONP tidak diterapkan. Saat Anda mengatur opsi crossOrigin menjadi true, plugin mengganti url asli dengan alamat Google Apps Script dan mengirimkannya sebagai parameter url yang disandikan. Skrip Google Apps menggunakan sumber daya Server Google untuk mendapatkan data jarak jauh, dan mengembalikannya ke klien sebagai JSONP.

Sangat mudah digunakan:

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

Anda dapat membaca lebih lanjut di sini: http://www.ajax-cross-origin.com/


22
Sejauh yang saya ketahui, plugin ini tidak pernah berfungsi. Itu tidak melakukan apa pun di Chrome.
Michael

Bagaimana saya bisa mengautentikasi ke server?
sttaq

bekerja hebat! API yang saya gunakan tidak mendukung JSONP atau CORS jadi ini adalah satu-satunya hal yang berfungsi. Terima kasih banyak!
JP Lew

crossOriginOpsi jQuery tentu saja tidak melakukan apa pun untuk memitigasi kebijakan yang sama-asal. Saya akan menghapus jawaban ini jika saya bisa
Phil

13

Jika situs eksternal tidak mendukung JSONP atau CORS, satu-satunya pilihan Anda adalah menggunakan proxy.

Buat skrip di server Anda yang meminta konten itu, lalu gunakan jQuery ajax untuk menekan skrip di server Anda.


5

Masukkan saja ini di header Halaman PHP Anda dan itu tidak berfungsi tanpa API:

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

atau

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

atau

$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");
}

Saya bertanya-tanya dari mana $_SERVER['HTTP_ORIGIN']datangnya. Saya tidak dapat menemukannya di dokumentasi PHP atau di mana pun.
Zsolti

Hmm, sepertinya hanya diisi dengan permintaan AJAX. Bagaimanapun, terima kasih atas jawabannya.
Zsolti

0

Saya memposting ini jika seseorang menghadapi masalah yang sama dengan yang saya hadapi saat ini. Saya punya printer thermal Zebra, dilengkapi dengan server cetak ZebraNet, yang menawarkan antarmuka pengguna berbasis HTML untuk mengedit beberapa pengaturan, melihat status printer saat ini, dll. Saya perlu mendapatkan status printer, yang ditampilkan di salah satu halaman html tersebut, ditawarkan oleh server ZebraNet dan, misalnya, memberi peringatan () pesan kepada pengguna di browser. Ini berarti saya harus mendapatkan halaman html itu dalam Javascript terlebih dahulu. Meskipun printer berada dalam LAN PC pengguna, Kebijakan Asal Samamasih tetap tegas di jalan saya. Saya mencoba JSONP, tetapi server mengembalikan html dan saya belum menemukan cara untuk memodifikasi fungsinya (jika saya bisa, saya sudah akan mengatur header ajaib Access-control-allow-origin: *). Jadi saya memutuskan untuk menulis aplikasi konsol kecil di C #. Itu harus dijalankan sebagai Admin untuk bekerja dengan baik, jika tidak troll: D pengecualian. Ini beberapa kode:

// 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();

Yang perlu dilakukan pengguna hanyalah menjalankan aplikasi konsol itu sebagai Admin. Saya tahu ini terlalu ... membuat frustrasi dan rumit, tetapi ini semacam solusi untuk masalah Kebijakan Domain jika Anda tidak dapat memodifikasi server dengan cara apa pun.

edit: dari js saya membuat panggilan ajax sederhana:

$.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 halaman yang diminta dikembalikan dan disimpan dalam variabel data .


0

Untuk mendapatkan data formulir situs eksternal dengan melewati menggunakan proxy lokal seperti yang disarankan oleh jherax Anda dapat membuat halaman php yang mengambil konten untuk Anda dari url eksternal masing-masing dan daripada mengirim permintaan dapatkan ke halaman php itu.

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

sebagai proxy php Anda dapat menggunakan https://github.com/cowboy/php-simple-proxy


0

Anda URLtidak berfungsi hari ini, tetapi kode Anda dapat diperbarui dengan solusi yang berfungsi ini:

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

Anda memerlukan proxy CORS yang mem-proksi permintaan Anda dari browser Anda ke layanan yang diminta dengan header CORS yang sesuai . Daftar layanan tersebut ada dalam cuplikan kode di bawah ini. Anda juga dapat menjalankan cuplikan kode yang disediakan untuk melihat ping ke layanan tersebut dari lokasi Anda.

$('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
Ini tidak menjawab pertanyaan dengan cara apa pun.
0xc0de

@ 0xc0de saya akhirnya menulis jawaban.
galeksandrp

-7

Menemukannya. Gunakan ini sebagai gantinya.

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

Kode yang Anda gunakan di sana tidak relevan. Yang penting adalah header sisi server CORS.
Quentin
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.