node.js 使用 express 在 axios post 请求之后进行重定向

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49601795/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 18:45:02  来源:igfitidea点击:

Making redirects after an axios post request with express

node.jsreactjsexpressredirectaxios

提问by asdfghjklm

I'm having trouble getting redirects to work after accepting a post request from Axios. I do know that the request is being sent and that it at least gets some response from the '/' route, because my console logs "index", "user verified" which is what should happen when someone makes a get request to '/'. The problem is that the page doesn't load. I've even seen in the networking tab on google chrome that index.js is loaded but the page will not change no matter what I've tried! Is there any reason for this?

在接受来自 Axios 的发布请求后,我在重定向工作时遇到了问题。我确实知道请求正在发送并且它至少从“/”路由得到一些响应,因为我的控制台记录了“索引”、“用户验证”,这是当有人向 '/ 发出获取请求时应该发生的情况'。问题是页面无法加载。我什至在 google chrome 的网络选项卡中看到 index.js 已加载,但无论我尝试什么,页面都不会改变!这有什么原因吗?

Other redirects that I've made do seem to work. For example, the index page will reroute to /login if the user is not logged in. This seems to only be an issue with the post request and I have tested it with and without passport authentication (obviously changed that you would need to be logged in to redirect) and it's the same result. So I do not think passport is causing the issue.

我所做的其他重定向似乎有效。例如,如果用户未登录,索引页面将重新路由到 /login。这似乎只是 post 请求的一个问题,我已经在使用和不使用护照身份验证的情况下对其进行了测试(显然已更改为您需要登录在重定向),它是相同的结果。所以我不认为护照是造成这个问题的原因。

You can refer to package.json below to see what I am using

你可以参考下面的 package.json 看看我在用什么

axios code:

轴代码:

axios.post('/login', {username: username, password: password})
        /*.then(response => res.redirect('/'))*/
        .then(function (response) {
            console.log(response);
        })
        .catch(function(error) {
            console.log(error);
        })

express side: I have console logs to alert myself during testing

快递方面:我有控制台日志可以在测试期间提醒自己

 server.get('/', (req,res) =>{
    console.log("Index");
  if (req.user){
       console.log("user verified");
        res.redirect('/');
        app.render(req,res, '/',req.query);
  } else {
      console.log("user not logged in");
      res.redirect('/login');
  }
})

server.post('/login', passport.authenticate('local'), (req, res, next) => {
    if (req.user) {
        console.log("Logging in");
        res.redirect('/');
  } else {
        console.log("Passwrod Incorrect");
        return res.redirect('/login');
  }
})

package.json

包.json

{
  "name": "layout-component",
  "version": "1.0.0",
  "scripts": {
    "dev": "node ./server.js",
    "build": "next build",
    "start": "NODE_ENV=production node ./server.js"
  },
  "dependencies": {
    "@zeit/next-css": "^0.1.5",
    "axios": "^0.18.0",
    "bcryptjs": "^2.4.3",
    "body-parser": "^1.18.2",
    "connect-flash": "^0.1.1",
    "connect-mongo": "^2.0.1",
    "cookie-parser": "^1.4.3",
    "express": "^4.16.3",
    "express-session": "^1.15.6",
    "express-validator": "^5.1.0",
    "file-loader": "^1.1.11",
    "hoist-non-react-statics": "^2.5.0",
    "jsonwebtoken": "^8.2.0",
    "mongodb": "^3.0.5",
    "mongoose": "^5.0.12",
    "next": "^5.1.0",
    "passport": "^0.4.0",
    "passport-local": "^1.0.0",
    "prop-types": "^15.6.1",
    "react": "^16.3.0",
    "react-dom": "^16.3.0",
    "semantic-ui-css": "^2.3.1",
    "semantic-ui-react": "^0.79.0",
    "url-loader": "^1.0.1"
  },
  "license": "ISC"
}

回答by asdfghjklm

I figured this out after. Apparently, you cannot do a redirect from the server when you make an Axios post request. At least not the way that I was doing it (with the default Axios config.) You need to do the page change on the client side. Here's how I did it.

我后来想通了这一点。显然,当您发出 Axios 发布请求时,您无法从服务器进行重定向。至少不是我这样做的方式(使用默认的 Axios 配置)。您需要在客户端进行页面更改。这是我如何做到的。

This really stumped me because I was receiving data from my redirect route using the other method but the page wasn't loading.

这真的让我很难过,因为我使用另一种方法从重定向路由接收数据,但页面没有加载。

Also, for some reason using Next.js, the passport.js "successRedirect" and "failureRedirect" JSON doesn't seem to work. That's why I've written the routing the way I have and did not include those in the passport.authenticate() function. I hope this helps somebody!

此外,由于某种原因使用 Next.js,passport.js“successRedirect”和“failureRedirect”JSON 似乎不起作用。这就是为什么我已经按照我的方式编写了路由,并且没有将那些包含在 Passport.authenticate() 函数中。我希望这对某人有所帮助!

My Axios submit function:

我的 Axios 提交功能:

onSubmit = (e) => {
    e.preventDefault()
    const {username, password} = this.state;
    axios.post('/login', {username: username, password: password})
        .then(function (response) {
            if (response.data.redirect == '/') {
                window.location = "/index"
            } else if (response.data.redirect == '/login'){
                window.location = "/login"
            }
        })
        .catch(function(error) {
            window.location = "/login"
        })
}

The post request in my Express server

我的 Express 服务器中的 post 请求

server.post('/login', passport.authenticate('local'), (req, res, next) => {
    if (req.user) {
        var redir = { redirect: "/" };
        return res.json(redir);
  } else {
        var redir = { redirect: '/login'};
        return res.json(redir);
  }
})

回答by docta_faustus

Although it won't be a server-side redirect, this can be accomplished cleanly on the client-side with Axios' "interceptor" which can intercept requests or responses before they get passed to then/catch:

虽然它不会是服务器端重定向,但这可以在客户端使用 Axios 的“拦截器”干净利落地完成,它可以在请求或响应传递到then/之前拦截它们catch

// Add a request interceptor
axios.interceptors.request.use(function (config) {
    // Do something before request is sent
    return config;
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });

// Add a response interceptor
axios.interceptors.response.use(function (response) {
    // Do something with response data
    return response;
  }, function (error) {
    // Do something with response error
    return Promise.reject(error);
  });

https://github.com/axios/axios#interceptors

https://github.com/axios/axios#interceptors