cari
Rumahhujung hadapan webtutorial jsSelesaikan ralat yang dijana apabila jQuery menggunakan JSONP_jquery

Apakah itu domain? Cross-domain bermaksud mengakses data dalam satu domain dalam domain lain.

Jika anda hanya memuatkan kandungan domain lain tanpa mengakses data, domain silang adalah sangat mudah, seperti menggunakan iframe. Tetapi jika anda perlu memuatkan dan menggunakan data ini dari domain lain, ia akan menjadi lebih menyusahkan. Atas sebab keselamatan, penyemak imbas mempunyai sekatan ketat terhadap situasi ini dan beberapa tetapan perlu dibuat pada kedua-dua klien dan pelayan untuk melaksanakan permintaan merentas domain.

Pengenalan kepada JSONP JSONP

(JSON dengan Padding) ialah kaedah merentas domain yang biasa digunakan, tetapi ia hanya menyokong skrip JS dan data format JSON. Seperti namanya, JSONP
ialah cara teknikal yang menggunakan JSON sebagai shim untuk melaksanakan permintaan merentas domain. Prinsip asasnya adalah untuk mengambil kesempatan daripada fakta bahawa tag <script></script> HTML sememangnya merentas domain dan menggunakannya untuk memuatkan data JSON daripada domain lain Selepas pemuatan selesai, panggilan balik akan dijalankan secara automatik Fungsi memberitahu pemanggil. Proses ini memerlukan sokongan pelayan daripada domain lain, jadi pelaksanaan merentas domain dengan cara ini tidak sewenang-wenangnya. Sokongan JQuery untuk JSONP Objek Ajax JQuery menyokong permintaan merentas domain dalam mod JSONP dengan menentukan parameter crossDomain sebagai benar dan parameter dataType sebagai jsonp[1], atau menggunakan borang yang disingkatkan: kaedah getJSON()[2]. Contohnya:


Apabila menggunakan

getJSON

, anda perlu menentukan jsoncallback= dalam parameter Ini adalah fungsi panggil balik yang disebutkan sebelumnya ) untuk menggantikan bahagian tanda soal dalam parameter, dengan itu membentuk parameter dalam bentuk
// 设置crossDomain和dataType参数以使用JSONP
$.ajax({
 dataType: "jsonp",
 url: "http://www.example.com/xxx",
 crossDomain: true,
 data: {
  
 }
}).done(function() {
 // 请求完成时的处理函数
});

// 使用getJSON
$.getJSON("http://www.example.com/xxx&#63;jsoncallback=&#63;", {
 // 参数
}, function() {
 // 请求完成时的处理函数
});

jsoncallback=jQueryxxxxxxx

, dan kemudian gunakan kaedah GET bersama-sama dengan parameter lain untuk membuat permintaan. Apabila menggunakan kaedah pertama, selagi nilai parameter dataType ditentukan sebagai jsonp, JQuery akan secara automatik menambah parameter jsoncallback selepas alamat permintaan, jadi terdapat tidak perlu menambahnya secara manual.

Kecacatan permintaan merentas domain JQuery: pengendalian ralat Permintaan merentas domain mungkin gagal Contohnya, tetapan keselamatan pelayan pihak lain enggan menerima permintaan daripada kami (kami tiada dalam senarai amanah pihak lain), atau rangkaian tidak tersedia, atau pelayan pihak lain. ditutup, atau alamat permintaan atau parameter tidak betul dengan betul menyebabkan pelayan melaporkan ralat dan sebagainya. Dalam JQuery, apabila permintaan dihantar menggunakan ajax atau getJSON, objek jqXHR [3] akan dikembalikan. Objek ini melaksanakan protokol Promise, jadi kami boleh menggunakan antara muka selesai, gagal, sentiasa dan lain-lain untuk mengendalikan panggilan balik. Sebagai contoh, kita boleh menggunakannya dalam panggilan balik failnya untuk mengendalikan ralat apabila permintaan gagal:


这种方式能够处理“正常的错误”,例如超时、请求被中止、JSON解析出错等等。但它对那些“非正常的错误”,例如网络不通、服务器已关闭等情况的支持并不好。

例如当对方服务器无法正常访问时,在Chrome下你会在控制台看到一条错误信息:

JQuery不会处理该错误,而是选择“静静地失败”:fail回调不会执行,你的代码也不会得到任何反馈,所以你没有处理这种错误的机会,也无法向用户报告错误。

一个例外是在IE8。在IE8中,当网络无法访问时,<script></script>标签一样会返回加载成功的信息,所以JQuery无法根据<script>标签的状态来判断是否已成功加载,但它发现<script>标签“加载成功”后回调函数却没有执行,所以JQuery以此判断这是一个“解析错误”(回调代码没有执行,很可能是返回的数据不对导致没有执行或执行失败),因此返回的错误信息将是“xxxx was not called”,其中的xxxx为回调函数的名称。</script>

也就是说,由于IE8(IE7也一样)的这种奇葩特性,导致在发生网络不通等“非正常错误”时,JQuery反而无法选择“静默失败”策略,于是我们可以由此受益,得到了处理错误的机会。例如在这种情况下,上面的例子将会弹出“xxxx was not called”的对话框。

解决方案
当遇到“非正常错误”时,除了IE7、8以外,JQuery的JSONP在较新的浏览器中全部会“静默失败”。但很多时候我们希望能够捕获和处理这种错误。

实际上在这些浏览器中,<script>标签在遇到这些错误时会触发error事件。例如如果是我们自己来实现JSONP的话可以这样:</script>

var ele = document.createElement('script');
ele.type = "text/javascript";
ele.src = '...';
ele.onerror = function() {
  alert('error');
};
ele.onload = function() {
  alert('load');
};
document.body.appendChild(ele);

在新浏览器中,当发生错误时将会触发error事件,从而执行onerror回调弹出alert对话框:

但是麻烦在于,JQuery不会把这个<script></script>标签暴露给我们,所以我们没有机会为其添加onerror事件处理器。

下面是JQuery实现JSONP的主要代码:

jQuery.ajaxTransport( "script", function(s) {
 if ( s.crossDomain ) {
  var script,
   head = document.head || jQuery("head")[0] || document.documentElement;
  return {
   send: function( _, callback ) {
    script = document.createElement("script");
    script.async = true;
    ...
    script.src = s.url;
    script.onload = script.onreadystatechange = ...;
    head.insertBefore( script, head.firstChild );
   },
   abort: function() {
    ...
   }
  };
 }
});

可以看到script是一个局部变量,从外部无法获取到。

那有没有解决办法呢?当然有:

  • 自己实现JSONP,不使用JQuery提供的
  • 修改JQuery源码(前提是你不是使用的CDN方式引用的JQuery)
  • 使用本文介绍的技巧

前两种不说了,如果愿意大可以选择。下面介绍另一种技巧。

通过以上源码可以发现,JQuery虽然没有暴露出script变量,但是它却“暴露”出了<script>标签的位置。通过send方法的最后一句:</script>

head.insertBefore( script, head.firstChild );
可以知道这个动态创建的新创建标签被添加为head的第一个元素。而我们反其道而行之,只要能获得这个head元素,不就可以获得这个script了吗?head是什么呢?继续看源码,看head是怎么来的:

head = document.head || jQuery("head")[0] || document.documentElement;
原来如此,我们也用同样的方法获取就可以了,所以补全前面的那个例子,如下:

var xhr = $.getJSON(...);
// for "normal error" and ie 7, 8
xhr.fail(function(jqXHR, textStatus, ex) {
  alert('request failed, cause: ' + ex.message);
});
// for 'abnormal error' in other browsers
var head = document.head || $('head')[0] || document.documentElement; // code from jquery
var script = $(head).find('script')[0];
script.onerror(function(evt) {
  alert('error');
});

这样我们就可以在所有浏览器(严格来说是绝大部分,因为我没有测试全部浏览器)里捕获到“非正常错误”了。

这样捕获错误还有一个好处:在IE7、8之外的其他浏览器中,当发生网络不通等问题时,JQuery除了会静默失败,它还会留下一堆垃圾不去清理,即新创建的<script>标签和全局回调函数。虽然留在那也没什么大的危害,但如果能够顺手将其清理掉不是更好吗?所以我们可以这样实现onerror:</script>

// handle error
alert('error');

// do some clean

// delete script node
if (script.parentNode) {
  script.parentNode.removeChild(script);
}
// delete jsonCallback global function
var src = script.src || '';
var idx = src.indexOf('jsoncallback=');
if (idx != -1) {
  var idx2 = src.indexOf('&');
  if (idx2 == -1) {
  idx2 = src.length;
  }
  var jsonCallback = src.substring(idx + 13, idx2);
  delete window[jsonCallback];
}

这样一来就趋于完美了。

完整代码

function jsonp(url, data, callback) {
  var xhr = $.getJSON(url + '&#63;jsoncallback=&#63;', data, callback);

  // request failed
  xhr.fail(function(jqXHR, textStatus, ex) {
    /*
     * in ie 8, if service is down (or network occurs an error), the arguments will be:
     * 
     * testStatus: 'parsererror'
     * ex.description: 'xxxx was not called' (xxxx is the name of jsoncallback function)
     * ex.message: (same as ex.description)
     * ex.name: 'Error'
     */
    alert('failed');
  });

  // ie 8+, chrome and some other browsers
  var head = document.head || $('head')[0] || document.documentElement; // code from jquery
  var script = $(head).find('script')[0];
  script.onerror = function(evt) {
    alert('error');

    // do some clean

    // delete script node
    if (script.parentNode) {
      script.parentNode.removeChild(script);
    }
    // delete jsonCallback global function
    var src = script.src || '';
    var idx = src.indexOf('jsoncallback=');
    if (idx != -1) {
      var idx2 = src.indexOf('&');
      if (idx2 == -1) {
        idx2 = src.length;
      }
      var jsonCallback = src.substring(idx + 13, idx2);
      delete window[jsonCallback];
    }
  };
}

Kod di atas telah diuji di bawah IE8, IE11, Chrome, FireFox, Opera dan 360. 360 ialah versi kernel IE dan penyemak imbas lain belum diuji lagi.

Saya harap artikel ini akan membantu anda belajar dan membantu anda menyelesaikan ralat yang berlaku apabila jQuery menggunakan JSONP.

Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Rangka Kerja JavaScript: Menguasai Pembangunan Web ModenRangka Kerja JavaScript: Menguasai Pembangunan Web ModenMay 02, 2025 am 12:04 AM

Kuasa rangka kerja JavaScript terletak pada pembangunan yang memudahkan, meningkatkan pengalaman pengguna dan prestasi aplikasi. Apabila memilih rangka kerja, pertimbangkan: 1.

Hubungan antara JavaScript, C, dan penyemak imbasHubungan antara JavaScript, C, dan penyemak imbasMay 01, 2025 am 12:06 AM

Pengenalan Saya tahu anda mungkin merasa pelik, apa sebenarnya yang perlu dilakukan oleh JavaScript, C dan penyemak imbas? Mereka seolah -olah tidak berkaitan, tetapi sebenarnya, mereka memainkan peranan yang sangat penting dalam pembangunan web moden. Hari ini kita akan membincangkan hubungan rapat antara ketiga -tiga ini. Melalui artikel ini, anda akan mempelajari bagaimana JavaScript berjalan dalam penyemak imbas, peranan C dalam enjin pelayar, dan bagaimana mereka bekerjasama untuk memacu rendering dan interaksi laman web. Kita semua tahu hubungan antara JavaScript dan penyemak imbas. JavaScript adalah bahasa utama pembangunan front-end. Ia berjalan secara langsung di penyemak imbas, menjadikan laman web jelas dan menarik. Adakah anda pernah tertanya -tanya mengapa Javascr

Aliran node.js dengan typescriptAliran node.js dengan typescriptApr 30, 2025 am 08:22 AM

Node.js cemerlang pada I/O yang cekap, sebahagian besarnya terima kasih kepada aliran. Aliran memproses data secara berperingkat, mengelakkan beban memori-ideal untuk fail besar, tugas rangkaian, dan aplikasi masa nyata. Menggabungkan sungai dengan keselamatan jenis typescript mencipta powe

Python vs JavaScript: Pertimbangan Prestasi dan KecekapanPython vs JavaScript: Pertimbangan Prestasi dan KecekapanApr 30, 2025 am 12:08 AM

Perbezaan prestasi dan kecekapan antara Python dan JavaScript terutamanya dicerminkan dalam: 1) sebagai bahasa yang ditafsirkan, Python berjalan perlahan tetapi mempunyai kecekapan pembangunan yang tinggi dan sesuai untuk pembangunan prototaip pesat; 2) JavaScript adalah terhad kepada benang tunggal dalam penyemak imbas, tetapi I/O multi-threading dan asynchronous boleh digunakan untuk meningkatkan prestasi dalam node.js, dan kedua-duanya mempunyai kelebihan dalam projek sebenar.

Asal JavaScript: Meneroka Bahasa PelaksanaannyaAsal JavaScript: Meneroka Bahasa PelaksanaannyaApr 29, 2025 am 12:51 AM

JavaScript berasal pada tahun 1995 dan dicipta oleh Brandon Ike, dan menyedari bahasa itu menjadi C. 1.C Language menyediakan keupayaan pengaturcaraan prestasi tinggi dan sistem untuk JavaScript. 2. Pengurusan memori JavaScript dan pengoptimuman prestasi bergantung pada bahasa C. 3. Ciri lintas platform bahasa C membantu JavaScript berjalan dengan cekap pada sistem operasi yang berbeza.

Di sebalik tabir: Apa bahasa JavaScript?Di sebalik tabir: Apa bahasa JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript berjalan dalam penyemak imbas dan persekitaran Node.js dan bergantung pada enjin JavaScript untuk menghuraikan dan melaksanakan kod. 1) menjana pokok sintaks abstrak (AST) di peringkat parsing; 2) menukar AST ke bytecode atau kod mesin dalam peringkat penyusunan; 3) Laksanakan kod yang disusun dalam peringkat pelaksanaan.

Masa Depan Python dan JavaScript: Trend dan RamalanMasa Depan Python dan JavaScript: Trend dan RamalanApr 27, 2025 am 12:21 AM

Trend masa depan Python dan JavaScript termasuk: 1. Kedua -duanya akan terus mengembangkan senario aplikasi dalam bidang masing -masing dan membuat lebih banyak penemuan dalam prestasi.

Python vs JavaScript: Persekitaran dan Alat PembangunanPython vs JavaScript: Persekitaran dan Alat PembangunanApr 26, 2025 am 12:09 AM

Kedua -dua pilihan Python dan JavaScript dalam persekitaran pembangunan adalah penting. 1) Persekitaran pembangunan Python termasuk Pycharm, Jupyternotebook dan Anaconda, yang sesuai untuk sains data dan prototaip cepat. 2) Persekitaran pembangunan JavaScript termasuk node.js, vscode dan webpack, yang sesuai untuk pembangunan front-end dan back-end. Memilih alat yang betul mengikut keperluan projek dapat meningkatkan kecekapan pembangunan dan kadar kejayaan projek.

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

mPDF

mPDF

mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),

Pelayar Peperiksaan Selamat

Pelayar Peperiksaan Selamat

Pelayar Peperiksaan Selamat ialah persekitaran pelayar selamat untuk mengambil peperiksaan dalam talian dengan selamat. Perisian ini menukar mana-mana komputer menjadi stesen kerja yang selamat. Ia mengawal akses kepada mana-mana utiliti dan menghalang pelajar daripada menggunakan sumber yang tidak dibenarkan.

MantisBT

MantisBT

Mantis ialah alat pengesan kecacatan berasaskan web yang mudah digunakan yang direka untuk membantu dalam pengesanan kecacatan produk. Ia memerlukan PHP, MySQL dan pelayan web. Lihat perkhidmatan demo dan pengehosan kami.

Penyesuai Pelayan SAP NetWeaver untuk Eclipse

Penyesuai Pelayan SAP NetWeaver untuk Eclipse

Integrasikan Eclipse dengan pelayan aplikasi SAP NetWeaver.

VSCode Windows 64-bit Muat Turun

VSCode Windows 64-bit Muat Turun

Editor IDE percuma dan berkuasa yang dilancarkan oleh Microsoft