无法让 vanilla JS onreadystatechange 函数/readyState 4 工作
Posted
技术标签:
【中文标题】无法让 vanilla JS onreadystatechange 函数/readyState 4 工作【英文标题】:Cant get vanilla JS onreadystatechange function / readyState 4 to work 【发布时间】:2020-04-19 20:15:28 【问题描述】:我正在为 HotSpot 创建一个“登录”页面。一旦用户输入他/她的电子邮件,他们就可以访问互联网。
为了完成这项工作,我使用了两个 AJAX 函数。
-
点击提交后,用户名和密码被发送到路由器(授予用户互联网访问权限)
进行了第二次 AJAX 调用,这会将电子邮件保存到数据库中(在用户访问 Internet 之后(应该在他访问 Internet 之后,在他被重定向之前发送)。
目前,我无法获取...
xhr.onreadystatechange = function ()
var DONE = this.DONE || 4;
if (xhr.readyState === XMLHttpRequest.DONE)
...函数工作。
Ajax 调用很早,用户会立即被重定向,并且电子邮件不会保存在数据库中(我认为这是因为它们是在用户访问互联网之前发送的)。
您能给我的任何帮助将不胜感激。
html 文档
<!DOCTYPE html>
<html>
<head>
<meta content="text/html" />
<meta charset="utf-8" />
<title>HotSpot</title>
</head>
<body>
<!-- Email Form, which gets saved into the DB -->
<form accept-charset="utf-8" name="mail" onsubmit="return false;" method="post" id="mail">
<h1>Hotspot</h1>
<h2>To gain internet access, enter your email.</h2>
<br />
<input type="text" id="email" name="email" autofocus="autofocus" />
<br />
<input type="submit" value="Submit" id="submit_ok" name="submit_ok" /> <br />
</form>
<script type="text/javascript">
document.getElementById("submit_ok").addEventListener("click", SendAjax);
function SendAjax()
var email = document.getElementById("email").value;
console.log(email);
// Check if fields are empty
if (email=="")
alert("Please enter your email.");
// AJAX code to submit form
else
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://router/login', true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
xhr.send("popup=true&username=HSuser&password=SimpleUserPassword");
xhr.onreadystatechange = function ()
var DONE = this.DONE || 4;
if (xhr.readyState === XMLHttpRequest.DONE)
var xhr2 = new XMLHttpRequest();
xhr2.open('POST', 'http://server/insertDB.php', true);
xhr2.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
var useremail = document.getElementById("email").value;
xhr2.send("Email="+encodeURIComponent(useremail));
xhr2.onreadystatechange = function ()
var DONE = this.DONE || 4;
if (xhr2.readyState === XMLHttpRequest.DONE)
location.href = "http://server/redirected.html";
;
这个也试过了,还是不行。
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://router/login', true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
xhr.send("popup=true&username=HSuser&password=SimpleUserPassword");
xhr.onreadystatechange = function ()
var DONE = this.DONE || 4;
if (this.readyState === DONE)
etc etc
PHP 文档(我认为这对本例来说并不重要,但你知道……以防万一)
<?php
require ('connect.php');
$clean_email = "";
$cleaner_email = "";
if(isset($_POST['email']) && !empty($_POST['email']))
//sanitize with filter
$clean_email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
//sanitize with test_input
$cleaner_email = test_input($clean_email);
//validate with filter
if (filter_var($cleaner_email,FILTER_VALIDATE_EMAIL))
// email is valid and ready for use
echo "Email is valid";
//Email is a row inside the database
$stmt = $DB->prepare("INSERT INTO addresses (Email) VALUES (?)");
$stmt->bind_param("s", $cleaner_email);
$stmt->execute();
$stmt->close();
else
// email is invalid and should be rejected
echo "Invalid email, try again";
else
echo "Please enter an email";
function test_input($data)
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
$DB->close();
?>
编辑:
粘贴一个sn-p的代码,已经改变了。
else
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://router.login', true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
xhr.send("popup=true&username=HSuser&password=SimpleUserPassword");
var xhr2= new XMLHttpRequest();
var useremail = document.getElementById("email").value;
xhr.onreadystatechange = function ()
console.log(DONE);
var DONE = this.DONE || 4;
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200)
console.log(DONE);
console.log(xhr.status);
xhr2.open('POST', 'http://server.insertDB.php', true);
xhr2.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
xhr2.send("Email="+encodeURIComponent(useremail));
xhr2.send("Email="+encodeURIComponent(useremail));
我需要将 email 变量移到外面,否则我会收到未定义的错误。
我现在在xhr2.send
上遇到错误...
未捕获的 DOMException:无法在“XMLHttpRequest”上执行“发送”:对象的状态必须是 OPENED。在 HTMLInputElement.SendAjax
【问题讨论】:
在事件处理程序中,比如onreadystatechange
,this
可能不是你,而是xhr
。使用日志记录检查它,如果是这种情况,请将“您的”this
保存到闭包中的变量中(或者如果您真的想要,也可以将其添加到 xhr
)。
公平地说,这句话对我来说没有多大意义。我对this
语句以及它们给我带来的麻烦并不是那么有经验。我将如何记录这个?控制台日志(完成);我假设?这个函数的文档可以在这里找到 --> en.wikipedia.org/wiki/…
做了 console.log(DONE);它确实得到了 4。我用调试器完成了它,发送第一个 AJAX 花了大约 5 秒。
【参考方案1】:
您必须在发送请求之前设置您的侦听器。这里是一个使用 onload 监听器的例子
// Set up our HTTP request
var xhr = new XMLHttpRequest();
// Setup our listener to process completed requests
xhr.onload = function ()
// Process our return data
if (xhr.status >= 200 && xhr.status < 300)
// What do when the request is successful
console.log('success!', xhr);
else
// What do when the request fails
console.log('The request failed!');
// Code that should run regardless of the request status
console.log('This always runs...');
;
// Create and send a GET request
// The first argument is the post type (GET, POST, PUT, DELETE, etc.)
// The second argument is the endpoint URL
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts');
xhr.send();
这里是一个准备状态变化监听器的例子
xhr.open(method, url, true);
xhr.onreadystatechange = function ()
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200)
console.log(xhr.responseText);
;
xhr.send();
这是您的代码,调用顺序正确
function SendAjax()
var email = document.getElementById("email").value;
console.log(email);
// Check if fields are empty
if (email=="")
alert("Please enter your email.");
// AJAX code to submit form
else
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://router/login', true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
xhr.onreadystatechange = function ()
var DONE = this.DONE || 4;
if (xhr.readyState === XMLHttpRequest.DONE)
var xhr2 = new XMLHttpRequest();
xhr2.open('POST', 'http://server/insertDB.php', true);
xhr2.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
var useremail = document.getElementById("email").value;
xhr2.onreadystatechange = function ()
var DONE = this.DONE || 4;
if (xhr2.readyState === XMLHttpRequest.DONE)
location.href = "http://server/redirected.html";
;
xhr2.send("Email="+encodeURIComponent(useremail));
xhr.send("popup=true&username=HSuser&password=SimpleUserPassword");
【讨论】:
好吧,我没有请求任何东西,所以我不知道为什么我需要 onload 函数,尤其是如果我的 xhr 请求超出了函数的范围... 当然你在请求一个 POST 请求“XMLHttpRequestEventTarget.onload 是当一个 XMLHttpRequest 事务成功完成时调用的函数。” onload 监听器不是这里的重点,重点是您必须在发送请求之前设置监听器。我已经添加了另一个示例 感谢您的澄清。我会试一试,然后告诉你会发生什么。 等等。现在我更加困惑了。当我们甚至还没有设置 xhr 时(因为它在括号之外),怎么能完成 xhr.readyState。以上是关于无法让 vanilla JS onreadystatechange 函数/readyState 4 工作的主要内容,如果未能解决你的问题,请参考以下文章
将 jQuery each() 循环重新设计为 Vanilla JS
node.js 的新手;需要帮助将 npm 模块导入我的前端 vanilla JS 项目
混合 Angular 1.x + Angular 6 应用程序,在 Angular 1.x 中包含 vanilla JS 和 TS 文件