登录系统在 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/jsonapplication/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/jsonapplication/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 中工作正常

文件上传错误 - 在 Postman 中有效,但在前端无效

身份验证(JWT)在本地有效,但在 Heroku 无效?

请求在 Chrome、Insomnia、Postman 等中可以正常运行,但在 Node 中却不行

GET API 在浏览器中显示 KeyError,但在 Postman 中工作