首页 > 解决方案 > 通过 Node.js 使用 AJAX 登录 POST 请求

问题描述

我正在尝试通过 Node.js 使用 javascript 为登录页面发送 AJAX POST 请求,但是我真的不知道该怎么做。抱歉,我对此真的很陌生。这是我的代码:

在 HTML 中:

<form>
  <label for="email"><b>Email Address</b></label><br>
  <input type="text" name="email"><br>
  <label for="password"><b>Password</b></label><br>
  <input type="text" name="password"><br><br>
  <input type="submit" class = "button" value="Login" onclick= "submitlogin()">
</form>

在 JS 中:

function submitlogin(){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function(){
if(this.readyState ==4 && this.status == 200){
        console.log("success");
} else if (this.readyState == 4 && this.status == 401) {
        console.log("Failed");
}
};
xhttp.open("POST","/login",true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.send(JSON.stringify({ email: this.email, password: this.password }));
}

路线:

var user = [{
            EmailAddress: 'anne@gmail.com',
            Password: 'first'
        }]

router.post('/login', function(req, res, next) {
if((req.body.email === user[0].EmailAddress) && user[0].Password === req.body.password){
  res.status(200).send();
} else {
  res.status(401).send();
}
});

xhttp.send() 应该包含什么?我做错了什么?谁能帮我这个?(最好只是 javascript 而不是 jQuery)谢谢!

标签: javascriptnode.jsajaxpostxmlhttprequest

解决方案


这是一个典型的问题,关于如何使用您意想不到的方式处理传递给服务器的信息。

您的代码中有很多需要改进的地方,但我现在不会专注于此。因此,首先,如果您注意单击提交按钮后浏览器中发生的情况,您可以在 URL 上看到查询字符串格式的输入。它没有引用描述的 /login 路由。

就像是:

http://localhost:3000/?email=marcelobraga%40hotmail.com&password=agoodpassword

发生这种情况是因为 Form 元素默认使用参数与您的服务器通信。不是您希望通过 HTTP 请求对象接收的对象“正文”。

如果您真的想访问作为 URL 参数传递的登录数据,您只需在前端和后端修复代码以正确传递对象并准备您的服务器以在正确的位置读取它。

我强烈建议您不要以这种方式使用表单 html 元素。要么使用 XMLHttpRequest。我建议使用 Axios 来处理 HTTP 请求并发送 Body 信息,以避免像登录这样的显式敏感信息。使用 Axios 的其他原因是简单的语法和干净的代码。

看看我是如何用 axios 做到的:

在 HTML 中(我会插入所有的 HTML 给你看导入的 Axios Lib 标签):

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <!-- importing axios to this document -->
    <title>Document</title>
</head>
<body>
    <label for="email"><b>Email Address</b></label><br>
    <input type="text" id="email" name="email"><br>
    <label for="password"><b>Password</b></label><br>
    <input type="text" id="password" name="password"><br><br>
    <input type="submit" class="button" value="Login" onclick="submitlogin()">
</body>
</html>

在 JS 文件中:

        const emailInput = document.getElementById("email").value //getting the value from input typed
        const passwordInput = document.getElementById("password").value //getting the value from input typed

        axios.post('/login', 
        {
            email: emailInput,
            password: passwordInput
        }
    )}; 

在 expressjs 中:

const express = require("express")
const app = express();
const path = require('path');

app.use(express.json()); 
app.use(express.urlencoded({ extended: true }));

app.post('/login', (req, res) => {
    console.log(req.body); //console to verify the body data received on this endpoint request

    const user = [{
        EmailAddress: 'anne@gmail.com',
        Password: 'first'
    }];

    if((req.body.email === user[0].EmailAddress) && user[0].Password === req.body.password){
        res.status(200).send("Success");
        console.log("Success");
      } else {
        res.status(401).send("Wrong email or password");
        console.log("Wrong email or password");
      }
});

app.get('/', function (req, res) {
    res.sendFile(path.join(__dirname + '/index.html'));
});

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

结论

您这样做的方式使后端的数据无法访问。后端期望收到信息以继续对请求的正文数据进行验证。您将它作为查询参数传递。

您可以使用 params 或 query params 将信息传递给后端,但必须对登录信息进行更多保护。例如,将其发送到您的身体中可避免人们在您的历史记录中查找此数据。这不是最安全的方式,因为有人可以在中间捕获这些数据。但是,无论如何,这是你应该知道的。

我希望我能帮助你。


推荐阅读