【问题标题】:res.redirect from an AJAX call来自 AJAX 调用的 res.redirect
【发布时间】:2017-10-13 17:53:47
【问题描述】:

我正在尝试在 ajax put 请求之后进行重定向。我打算使用纯 JS 客户端进行验证。

客户:

$(document).ready(function() {
    login = () => {
        var username = $("[name='username']").val()
        var password = $("[name='password']").val()
        $.ajax({
            type: "put",
            url: '/login',
            data: {
                username: username,
                password: password
            }
            // success: function(response) {
            //  console.log('Success:')
            //  console.log(response.user)

            //  Cookies.set('username', response.user.username)
            //  Cookies.set('first_name', response.user.first_name)
            //  Cookies.set('last_name', response.user.last_name)
            //  Cookies.set('email', response.user.email)

            //  window.location.href = window.location.origin + '/'
            // },
            // error: function(error) {
            //  console.log("Error:")
            //  console.log(error)
            // }
        })
    }

    logout = () => {
        console.log("Log out clicked.")
        Cookies.remove('username')
        Cookies.remove('first_name')
        Cookies.remove('last_name')
        Cookies.remove('email')
        window.location.href = window.location.origin + '/logout'
    }
})

服务器:

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('main')
});

router.put('/login', function(req, res) {
    // Password is not encrypted here
    console.log('req.body')
    console.log(req.body)

    User.findOne({ username: req.body.username }, function(err, user) {
        // Password is encrypted here
        if (err) throw err
        console.log('user')
        console.log(user)

        bcrypt.compare(req.body.password, user.password, function(err, result) {
            if (result) {
                var token = jwt.encode(user, JWT_SECRET)
                // return res.status(200).send({ user: user, token: token })
                return res.redirect('/')
            } else {
                return res.status(401).send({error: "Something is wrong."})
            }
        })
    })
})

成功登录后我无法让main.hbs 呈现。我的注释代码有效,但我正在尝试做我的重定向服务器端而不是客户端,因为我被告知它对安全性更好。

【问题讨论】:

  • 您的注释代码是正确的工作方式。这里没有安全性损失。无论哪种方式,您的重定向都会传达给用户。服务器端重定向对于 ajax 请求是死路一条,因为该指令不是针对浏览器的,而是针对一些 javascript 处理程序的。
  • 谢谢!这真是太好了。我的注释代码对我来说很有意义,我想朝那个方向发展,但我担心用户的安全性。如果我能够在客户端使用 JavaScript(在向服务器提交请求之前),我将能够进行自定义验证,而不是仅限于 HTML5 表单验证。

标签: javascript jquery ajax express


【解决方案1】:

您应该知道何时使用hrefreplace 功能。

window.location.replace(...) 是表示 HTTP 重定向的最佳方式。

原因

window.location.href 相比,window.location.replace(...) 更适合在 HTTP 重定向场景中使用,因为replace() 避免将原始页面保留在会话历史记录中,这有助于用户避免陷入永无止境的后端 -按钮惨败。

总结

如果您想说明点击链接,请使用location.href

如果您想说明 HTTP 重定向,请使用 location.replace

示例

//  an HTTP redirect
window.location.replace("http://example.com");

//  clicking on a link
window.location.href = "http://example.com";

更新

服务器无法从 ajax 请求进行重定向。最后ajax涉及到客户端(浏览器)。

如果您愿意,您可以通过服务器端调用发送重定向指令,但它会再次在客户端,在回调中结束。 您可以通过从服务器返回一个包含您要重定向到的 url 的对象来做到这一点。然后使用 javascript 更改文档的位置属性。如下:

服务器端代码

if (result) {
    var token = jwt.encode(user, JWT_SECRET)
    return res.status(200).send({result: 'redirect', url:'/'})
} else {
    return res.status(401).send({error: "Something is wrong."})
}

然后在客户端 Javascript 中:

$.ajax({
  type: "put",
  url: '/login',
  data: {
    username: username,
    password: password
  }
  success: function(response) {
    if (response.result == 'redirect') {
      //redirecting to main page from here.
      window.location.replace(response.url);
    }

  }
});

除此之外,您的注释代码是执行此操作的正确方法。就像您提出的问题中的一个 cmets 一样,“服务器端重定向对于 ajax 请求是死路一条,因为该指令不是针对浏览器的,而是针对一些 javascript 处理程序的。”

【讨论】:

  • 感谢您的解释!问题:在安全性方面,一种方法比另一种更好吗?根据你的解释,我猜location.replace 是要走的路。
  • @Farid 是的,在你想要重定向的地方使用location.replace
  • @Farid 如果答案有用且正确,您可以将其标记为正确答案!
  • 安全性怎么样? location.replace 是一种安全的使用方法吗?
  • 这不是切线吗?他要求服务器端重定向他的页面,而不是客户端代码。你说的是对的,但他的服务器端代码不允许更改窗口位置,不是吗?
【解决方案2】:

我认为你想做的事情是不可能的。 AJAX 请求只是为了来回传递数据。现在发生的情况是,您需要在终端上编写客户端行为脚本。这意味着 AJAX 请求将传递一个 302 和其他随乘车而来的数据到 JS 上的回调。不能从服务器更改任何客户端行为。您可以对 AJAX 返回的值做一些事情。如果 500,则抛出错误消息,200 做某事等。

使服务器重定向工作的唯一方法是通过传统的 HTML 表单提交。

【讨论】:

  • 好的,所以我想我是在我的注释代码中做到了这一点,我在客户端使用window.location.href = window.location.origin + '/' 进行了重定向。对于登录系统,是否最好只使用传统的 HTML 提交以便重定向发生在服务器端?
  • 与所有事情一样,这取决于。如果您正在做一个纯单页应用程序,那么使用客户端的东西。但是,从您的代码来看,您不是。在我看来,基本的服务器端重定向更适合这里。如果您登录到 GMail 或其他什么,他们也会进行服务器端重定向。希望这会有所帮助。
  • 我想问的其他问题:为了进行服务器端重定向,如您所述,我想我需要绕过客户端 JS(这是我上面的代码目前的工作方式) .如果我想在客户端使用 JS 进行自定义验证(超出 HTML5 表单验证可用的功能),这可能吗?
  • 为什么不呢?您始终可以将一个或多个表单提交侦听器附加到您想要的控件,并在 JS 中做任何可能的事情。
猜你喜欢
  • 2012-07-19
  • 2023-03-03
  • 2015-02-13
  • 2018-04-04
  • 2022-01-19
  • 2012-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多