登录系统在 Postman 中正常工作,但在浏览器中不能正常工作
Posted
技术标签:
【中文标题】登录系统在 Postman 中正常工作,但在浏览器中不能正常工作【英文标题】:Login system works properly in Postman but in not in browser 【发布时间】:2020-10-25 06:48:47 【问题描述】:这是我的路由器
router.post("/login", async (req, res) =>
try
const user = await User.findByCredentials(req.body.email, req.body.password)
// console.log(user)
const token = await user.generateAuthToken()
// console.log(token)
res.redirect("/takvim")
catch(e)
res.status(400).redirect("/")
)
这是我在上述函数中使用的用户模型
UserSchema.methods.generateAuthToken = async function ()
const user = this
const token = jwt.sign(_id: user._id.toString(), "secret")
user.tokens = user.tokens.concat(token)
await user.save()
return token
UserSchema.statics.findByCredentials = async function (emails, passwords)
const user = await User.findOne(email: emails)
console.log(user)
const isMatch = await bcrypt.compare(passwords, user.password)
if(!isMatch)
throw new Error("unable to login")
return user
我正在使用按钮从前端发出请求
$uyeolForm.addEventListener("submit", () =>
if(!$uyeolFormEmail.value.includes(".com"))
return $uyeolFormHata.innerhtml = "email geçersiz"
const xhr = new XMLHttpRequest();
let form = JSON.stringify(
email: $uyeolFormEmail.value,
password: $uyeolFormPassword.value
);
xhr.open("POST", "/login")
xhr.setRequestHeader('Content-type', 'application/json')
xhr.send(form);
)
问题是当我使用邮递员时,应用程序将我重定向到我想要的页面并且没有给出错误。
当我使用按钮发送请求时,它仍然可以找到用户,但它没有将我重定向到我期望的页面,并且在控制台中我看到了用户(期望)和null
,这是不期望的。
谢谢大家。
【问题讨论】:
status(400)
— 这是“请求格式不正确,服务器不知道如何处理”的错误代码。 “您的凭据不匹配”和重定向响应 the spec implies the code should be 201 or 3xx 是完全错误的
【参考方案1】:
当submit
事件被触发时,您正在使用 XMLHttpRequest 发出 HTTP 请求,但您并未阻止表单提交的默认行为。
因此,XMLHttpRequest 对象被创建并发出请求,然后紧接着(可能会根据事情进展的速度取消请求)<form>
被提交到 @ 中指定的 URL 987654323@.
您说端点被击中了两次,一次是您获得预期的用户,另一次是您没有获得的用户。
当您获得您期望的用户时,它来自 XHR 提交。
如果你不这样做,那是来自常规表单提交(它不会被 JSON 编码为 HTML 表单不支持 JSON 编码,所以它找不到用户,因为它不解码数据表格正确)。
既然你说你想重定向,不要使用 Ajax。 Ajax 是一种无需离开当前页面即可发出 HTTP 请求的方法。
更改服务器端代码以接受 <form>
编码格式的数据(可能是 application/x-www-form-urlencoded
,除非您使用 enctype
属性更改它)。
【讨论】:
感谢这个有用的答案。如果我想重定向,我应该如何从客户端 js 获取数据并将其发送到后端? 在表单中生成隐藏输入。【参考方案2】:您总是想知道错误消息是什么。添加一个 console.error(JSON.stringify(e)) 在回复之前,告诉我们它说了什么。
catch(e)
console.error(JSON.stringify(e));
res.status(400).redirect("/");
【讨论】:
【参考方案3】:如果您打算使用application/json
和application/x-www-form-urlencoded
来支持ajax 和通常的表单提交方式 - 您必须通过reading Location header 在前端级别重定向它:
$uyeolForm.addEventListener("submit", (event) =>
event.preventDefault();
if(!$uyeolFormEmail.value.includes(".com"))
return $uyeolFormHata.innerHTML = "email geçersiz"
fetch('/login',
method: "POST",
credentials: "include",
headers:
"Content-Type": "application/json",
,
body: JSON.stringify(
email: $uyeolFormEmail.value,
password: $uyeolFormPassword.value
)
)
.then(function(response)
if (response.redirected)
const redirectTo = response.headers.get('Location');
if (redirectTo)
window.location.href = redirectTo;
return;
)
.catch(function(error)
alert(error.message);
);
)
请记住,要同时支持 application/json
和 application/x-www-form-urlencoded
,您必须附加 2 个正文解析器作为中间件:
const bodyParser = require('body-parser');
router.use(bodyParser.urlencoded(true));
router.use(bodyParser.json());
【讨论】:
以上是关于登录系统在 Postman 中正常工作,但在浏览器中不能正常工作的主要内容,如果未能解决你的问题,请参考以下文章
GET 请求在浏览器中有效,但在 POSTMAN 或 SOAPUI 中无效
PHP Curl 请求不起作用,但在 POSTMAN 中工作正常