来自 AJAX 调用的 res.redirect
Posted
技术标签:
【中文标题】来自 AJAX 调用的 res.redirect【英文标题】:res.redirect from an AJAX call 【发布时间】: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 表单验证。 【参考方案1】:您应该知道何时使用href
和replace
功能。
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 中做任何可能的事情。以上是关于来自 AJAX 调用的 res.redirect的主要内容,如果未能解决你的问题,请参考以下文章