Über das Cookie-Problem der Ajax-Synchronisierung
Vorwort
Es ist wirklich hilflos, auf ein solches Problem zu stoßen.
Dieser Artikel beschreibt nur einen so peinlichen und hilflosen Tag. Benutzen Sie es, um allen die Langeweile zu vertreiben T_T
Stellen Sie die Szene nach
Kollege: Komm schon! Aufleuchten! Im Internet ist ein Fehler aufgetreten! !
Ich: Wow?! WAS?!
Kollege: Liegt es an dieser Veröffentlichung?
Ich: Roll back! Rollback! (Warum verlierst du die Beherrschung, wenn du gerade essen willst? Mach dir keine Sorgen um deinen Magen! Schau es dir schnell an)
...
Ich kann mich erst nach einer Weile beruhigen verwirrendes Gespräch. „Minesweeper“.
Rollback, Proxy, Paketerfassung, Vergleich, Einzelfaktor-Fehlerbehebung. . .
Nachdem ich eine Reihe von Combo-Schlägen ausgeführt hatte, dauerte es etwa ein Räucherstäbchen, um den Fehler endlich zu finden. Es stellte sich heraus, dass es sich um ein Problem mit dem Ajax-Synchronisations-Callback handelte! Unvernünftig! Das sollte nicht sein! Gibt es eine solche Operation? !
Wiedergabe des Problems
Zusammenfassung des Problems in einem Satz
Verwenden Sie Ajax, um eine „Synchronisierungsanfrage“ zu stellen gibt ein Cookie zurück.
success
Dieses Ziel-Cookie konnte im Rückruf nicht gelesen werden!document.cookie
wird erst aktualisiert, wenn die Ajax-Ausführung abgeschlossen ist
Einflussbereich
Der Einflussbereich auf PC und Android ist gering und gelegentlich.
IOS ist der am stärksten betroffene Bereich, außer Chrome und Safari, und auch die integrierte Webview-Umgebung der App ist nicht immun.
Das Vorablesen des von dieser Anfrage zurückgegebenen Cookies innerhalb dieses synchronen Anfragerückrufs führt zu Problemen.
Das halbe Land ist gefallen, welchen Nutzen habe ich mit dieser Eisenstange!
Ursache und Wirkung aufspüren
Das kleine Kompatibilitätsproblem kann ich dir verzeihen, aber du bist so arrogant, wie kannst du es verbergen!
Vertikaler Vergleich
Um einige Interferenzelemente zu beseitigen und ihr Wesen wiederherzustellen, verwenden wir die Frameworks nej
, jQuery
und js
, um mehrere „Synchronisationen“ mit dem zu schreiben Gleiche Funktion. Demo, abwarten. .
[nej.html] Verwenden Sie die NEJ-Bibliothek
<!DOCTYPE html> <html> <head> <title>nej</title> <meta charset="utf-8" /> </head> <body> test <script src="http://nej.netease.com/nej/src/define.js?pro=./"></script> <script> define([ '{lib}util/ajax/xdr.js' ], function () { var _j = NEJ.P('nej.j'); _j._$request('/api', { sync: true, method: 'POST', onload: function (_data) { alert("cookie:\n" + document.cookie) } }); }); </script> </body> </html>
[jquery.html] Verwenden Sie die jQuery-Bibliothek
<!DOCTYPE html> <html> <head> <title>jquery</title> <meta charset="utf-8" /> </head> <body> jquery <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <script> $.ajax({ url: '/api', async: false, method: 'POST', success: function (result) { alert("cookie:\n" + document.cookie) } }); </script> </body> </html>
[js.html] Implementieren Sie Ihre eigene Ajax-Anfrage Die Funktionen
<!DOCTYPE html> <html> <head> <title>JS</title> <meta charset="utf-8" /> </head> <body> js <script> var _$ajax = (function () { /** * 生产XHR兼容IE6 */ var createXHR = function () { if (typeof XMLHttpRequest != "undefined") { // 非IE6浏览器 return new XMLHttpRequest(); } else if (typeof ActiveXObject != "undefined") { // IE6浏览器 var version = [ "MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp", ]; for (var i = 0; i < version.length; i++) { try { return new ActiveXObject(version[i]); } catch (e) { return null } } } else { throw new Error("您的系统或浏览器不支持XHR对象!"); } }; /** * 将JSON格式转化为字符串 */ var formatParams = function (data) { var arr = []; for (var name in data) { arr.push(name + "=" + data[name]); } arr.push("nocache=" + new Date().getTime()); return arr.join("&"); }; /** * 字符串转换为JSON对象,兼容IE6 */ var _getJson = (function () { var e = function (e) { try { return new Function("return " + e)() } catch (n) { return null } }; return function (n) { if ("string" != typeof n) return n; try { if (window.JSON && JSON.parse) return JSON.parse(n) } catch (t) { } return e(n) }; })(); /** * 回调函数 */ var callBack = function (xhr, options) { if (xhr.readyState == 4 && !options.requestDone) { var status = xhr.status; if (status >= 200 && status < 300) { options.success && options.success(_getJson(xhr.responseText)); } else { options.error && options.error(); } //清空状态 this.xhr = null; clearTimeout(options.reqTimeout); } else if (!options.requestDone) { //设置超时 if (!options.reqTimeout) { options.reqTimeout = setTimeout(function () { options.requestDone = true; !!this.xhr && this.xhr.abort(); clearTimeout(options.reqTimeout); }, !options.timeout ? 5000 : options.timeout); } } }; return function (options) { options = options || {}; options.requestDone = false; options.type = (options.type || "GET").toUpperCase(); options.dataType = options.dataType || "json"; options.contentType = options.contentType || "application/x-www-form-urlencoded"; options.async = options.async; var params = options.data; //创建 - 第一步 var xhr = createXHR(); //接收 - 第三步 xhr.onreadystatechange = function () { callBack(xhr, options); }; //连接 和 发送 - 第二步 if (options.type == "GET") { params = formatParams(params); xhr.open("GET", options.url + "?" + params, options.async); xhr.send(null); } else if (options.type == "POST") { xhr.open("POST", options.url, options.async); //设置表单提交时的内容类型 xhr.setRequestHeader("Content-Type", options.contentType); xhr.send(params); } } })(); _$ajax({ url: '/api', async: false, type: 'POST', success: function (result) { alert("cookie:\n" + document.cookie) } }); </script> </body> </html>
sind in den drei Dateien gleich. Nach dem Laden der HTML-Datei wird eine synchrone Anfrage initiiert. Im Rückruf wird document.cookie
ausgegeben um festzustellen, ob der Rückruf bereits ausgeführt wird. Das Cookie wird zu diesem Zeitpunkt geschrieben.
Im Folgenden wird Node verwendet, um diesen beschreibbaren Cookie-Dienst zu implementieren.
【serve.js】
var express = require("express"); var http = require("http"); var fs = require("fs"); var app = express(); var router = express.Router(); router.post('/api', function (req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With"); res.header("Set-Cookie", ["target=ccccccc|" + new Date()]); res.end('ok'); }); router.get('/test1', function (req, res, next) { fs.readFile("./nej.html", function (err, data) { res.end(data); }); }); router.get('/test2', function (req, res, next) { fs.readFile("./jquery.html", function (err, data) { res.end(data); }); }); router.get('/test3', function (req, res, next) { fs.readFile("./js.html", function (err, data) { res.end(data); }); }); app.use('/', router); http.createServer(app).listen(3000);
Okay, alles ist in Ordnung, lass uns
$ node serve.js
Operation
Wir führen die folgenden Operationen nacheinander aus,
Verwenden Sie den iOS-QQ-Browser und leeren Sie alle Caches
Laden Sie eine der Seiten und beobachten Sie, ob eine Ziel-Cookie-Ausgabe erfolgt
Führen Sie einen Aktualisierungsvorgang durch, beobachten Sie, ob eine Ziel-Cookie-Ausgabe vorliegt, vergleichen Sie den Zeitstempel der Cookie-Ausgabe und bestätigen Sie, ob es sich um das Synchronisierungsergebnis des letzten Cookies und nicht um das durch diese Anfrage erhaltene Cookie handelt ,
Alle Caches löschen, die Ziel-HTML-Datei wechseln und die Schritte 2, 3 und 4 in einer Schleife ausführen
Ergebnis
[nej.html]
Reines Umgebungsladen, das Zielcookie wird nicht gelesen
Aktualisieren Sie den Ladevorgang, das Cookie wird zurückgegeben von der vorherigen Anfrage wird gelesen
[jquery.html]
Reines Umgebungsladen, das Ziel-Cookie wird nicht gelesen
Laden aktualisieren, das Ziel-Cookie wird nicht gelesen
[js.html]
Reines Umgebungsladen, das Ziel-Cookie wird nicht gelesen
Laden aktualisieren, Ziel-Cookie wird nicht gelesen
Häh? Das Ergebnis ist anders! Der zweite Ladevorgang mit nej liest das erste Cookie. Die anderen beiden Zeiten wurden erhalten.
Grund
nej Das Laden des abhängigen Frameworks erfolgt asynchron. Wenn die synchrone Anfrage initiiert wird, wurde der Dom geladen. Wenn der Rückruf antwortet, ist document.cookie
im Zustand „Bereit“. Zustand und ist lesbar und schreibbar. Die Anfrage kann das zurückgegebene Cookie jedoch immer noch nicht selbst abrufen.
Die anderen beiden Lademechanismen blockieren das Laden von Dom, was dazu führt, dass der Dom nicht geladen wird, wenn die Synchronisierungsanforderung initiiert wird, wenn der Rückruf antwortet , document.cookie
Immer noch nicht beschreibbar.
Einzelfaktorkontrolle
Wir werden die Logik der oben genannten HTML-Dateien ändern.
Verzögern Sie die Synchronisierungsanforderung, bis auf das Dokument geklickt wird.
Das Folgende
$('document').click(function () { // TODO 发起同步请求 });
sind immer noch die oben genannten Ausführungsschritte, werfen wir einen Blick auf die Ergebnisse
Ergebnisse
[nej.html]
Reines Laden der Umgebung, das Ziel-Cookie wird nicht gelesen
Aktualisieren Sie den Ladevorgang, das von der vorherigen Anfrage zurückgegebene Cookie wird gelesen
【jquery.html】
Reines Umgebungsladen, das Zielcookie wird nicht gelesen
Laden aktualisieren, das letzte Mal wird gelesen. Das von der Anfrage zurückgegebene Cookie
[js.html]
wird in eine saubere Umgebung geladen und das Zielcookie wird nicht gelesen
刷新加载,读取到上一次请求返回的 cookie
结果和预期一样,本次请求无法获取本期返回的目标 cookie,请求回调执行后,目标cookie才会更新到document.cookie
上。
特例
在执行以上操作是,发现,【jquery.html】的执行结果时不时会有两种结果
纯净环境加载,未读取到目标 cookie
刷新加载,读取到上一次请求返回的 cookie
另外一种几率较小,但也会出现纯净环境加载,读取到目标 cookie
刷新加载,读取到目标 cookie
产生原因
一言不合看源码
我们在 jquery 的源码中看到,jquery 的success
回调绑定在了 onload
事件上
https://code.jquery.com/jquery-3.2.1.js :9533行
而我自己实现的和 nej 的实现均是将success
回调绑定在了 onreadystatechange
事件上,唯一的区别就在于此
一个正向的 ajax 请求,会先触发两次onreadystatechange
,在触发onload
,或许原因在于document.cookie
的同步有几率在onload
事件触发前完成??I'm not sure.
问题结论
在 PC 端,Android 端,IOS 端Chrome、Safari 浏览器环境下,ajax 的同步请求的回调方法中,取到本请求返回的 cookie 失败几率低
IOS 端,QQ 浏览器、App 内置Webview浏览器环境下,失败率极高。
解决方案
只有问题没有方案的都是在耍流氓!
方案1 - 明修栈道暗度陈仓
将回调方法中的 cookie 获取方法转化为异步操作。
_$ajax({ url: '/api', async: false, type: 'POST', success: function (result) { setTimeout(function(){ // do something 在此处获取 cookie 操作是安全的 },0) } });
方案2 - 不抵抗政策
没有把握的方案,我们是要斟酌着实施的。
如果你不能100%却被操作的安全性,那并不建议你强行使用 ajax 的同步操作,很多机制并不会像我们自以为是的那样理所应当。
Das obige ist der detaillierte Inhalt vonÜber das Cookie-Problem der Ajax-Synchronisierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Titel: Methoden und Codebeispiele zur Behebung von 403-Fehlern in jQuery-AJAX-Anfragen. Der 403-Fehler bezieht sich auf eine Anfrage, dass der Server den Zugriff auf eine Ressource verbietet. Dieser Fehler tritt normalerweise auf, weil der Anfrage die Berechtigungen fehlen oder sie vom Server abgelehnt wird. Wenn Sie jQueryAJAX-Anfragen stellen, stoßen Sie manchmal auf diese Situation. In diesem Artikel wird erläutert, wie dieses Problem gelöst werden kann, und es werden Codebeispiele bereitgestellt. Lösung: Berechtigungen prüfen: Stellen Sie zunächst sicher, dass die angeforderte URL-Adresse korrekt ist und stellen Sie sicher, dass Sie über ausreichende Berechtigungen für den Zugriff auf die Ressource verfügen.

jQuery ist eine beliebte JavaScript-Bibliothek zur Vereinfachung der clientseitigen Entwicklung. AJAX ist eine Technologie, die asynchrone Anfragen sendet und mit dem Server interagiert, ohne die gesamte Webseite neu zu laden. Wenn Sie jedoch jQuery zum Senden von AJAX-Anfragen verwenden, treten manchmal 403-Fehler auf. Bei 403-Fehlern handelt es sich in der Regel um vom Server verweigerte Zugriffsfehler, möglicherweise aufgrund von Sicherheitsrichtlinien oder Berechtigungsproblemen. In diesem Artikel besprechen wir, wie Sie bei einer jQueryAJAX-Anfrage den Fehler 403 beheben können

Immer mehr Benutzer beginnen mit der Aktualisierung des Win11-Systems. Da jeder Benutzer unterschiedliche Nutzungsgewohnheiten hat, verwenden viele Benutzer immer noch den IE11-Browser. Was soll ich also tun, wenn das Win11-System den IE-Browser nicht verwenden kann? Unterstützt Windows11 immer noch ie11? Werfen wir einen Blick auf die Lösung. Lösung des Problems, dass Win11 den ie11-Browser nicht verwenden kann 1. Klicken Sie zunächst mit der rechten Maustaste auf das Startmenü und wählen Sie „Eingabeaufforderung (Administrator)“, um es zu öffnen. 2. Geben Sie nach dem Öffnen direkt „Netshwinsockreset“ ein und drücken Sie zur Bestätigung die Eingabetaste. 3. Geben Sie nach der Bestätigung „netshadvfirewallreset&rdqu“ ein

Mit der Popularität des Internets ist die Verwendung von Browsern zum Surfen im Internet zu einer Lebensweise geworden. Bei der täglichen Verwendung von Browsern stoßen wir häufig auf Situationen, in denen wir Kontokennwörter eingeben müssen, z. B. beim Online-Shopping, bei sozialen Netzwerken, bei E-Mails usw. Diese Informationen müssen vom Browser aufgezeichnet werden, damit sie bei Ihrem nächsten Besuch nicht erneut eingegeben werden müssen. Was sind Cookies? Bei einem Cookie handelt es sich um eine kleine Datendatei, die vom Server an den Browser des Benutzers gesendet und lokal gespeichert wird. Sie enthält das Benutzerverhalten einiger Websites.

Wie kann das Problem des jQueryAJAX-Fehlers 403 gelöst werden? Bei der Entwicklung von Webanwendungen wird jQuery häufig zum Senden asynchroner Anfragen verwendet. Allerdings kann bei der Verwendung von jQueryAJAX manchmal der Fehlercode 403 auftreten, der darauf hinweist, dass der Zugriff vom Server verboten ist. Dies wird normalerweise durch serverseitige Sicherheitseinstellungen verursacht, es gibt jedoch Möglichkeiten, das Problem zu beheben. In diesem Artikel wird erläutert, wie Sie das Problem des jQueryAJAX-Fehlers 403 lösen können, und es werden spezifische Codebeispiele bereitgestellt. 1. machen

Erstellen Sie eine Engine für Autovervollständigungsvorschläge mit PHP und Ajax: Serverseitiges Skript: Verarbeitet Ajax-Anfragen und gibt Vorschläge zurück (autocomplete.php). Client-Skript: Ajax-Anfrage senden und Vorschläge anzeigen (autocomplete.js). Praktischer Fall: Fügen Sie ein Skript in die HTML-Seite ein und geben Sie die Kennung des Sucheingabeelements an.

Die Verwendung von Ajax zum Abrufen von Variablen aus PHP-Methoden ist ein häufiges Szenario in der Webentwicklung. Durch Ajax kann die Seite dynamisch abgerufen werden, ohne dass die Daten aktualisiert werden müssen. In diesem Artikel stellen wir vor, wie man Ajax verwendet, um Variablen aus PHP-Methoden abzurufen, und stellen spezifische Codebeispiele bereit. Zuerst müssen wir eine PHP-Datei schreiben, um die Ajax-Anfrage zu verarbeiten und die erforderlichen Variablen zurückzugeben. Hier ist ein Beispielcode für eine einfache PHP-Datei getData.php:

In letzter Zeit haben viele Win10-Benutzer festgestellt, dass ihr IE-Browser bei der Verwendung von Computerbrowsern immer automatisch zum Edge-Browser springt. Wie kann man also den automatischen Sprung zum Edge beim Öffnen des IE in Win10 deaktivieren? Lassen Sie diese Website den Benutzern sorgfältig vorstellen, wie sie beim Öffnen des IE in Win10 automatisch zum Rand springen und schließen. 1. Wir melden uns beim Edge-Browser an, klicken auf ... in der oberen rechten Ecke und suchen nach der Dropdown-Einstellungsoption. 2. Nachdem wir die Einstellungen eingegeben haben, klicken Sie in der linken Spalte auf Standardbrowser. 3. Abschließend aktivieren wir in der Kompatibilität das Kontrollkästchen, um ein erneutes Laden der Website im IE-Modus zu verhindern, und starten den IE-Browser neu.
