【问题标题】:Only certain cross origin requests working using npm cors()只有某些跨源请求使用 npm cors()
【发布时间】:2019-02-19 11:56:40
【问题描述】:

我正在使用 react 构建一个网站(它在 localhost:3000 上运行),它从我构建的在 localhost:4000 上运行的 API 获取其用户信息。为了允许两者之间的请求,我被告知使用 npm cors 包来允许来回跨域请求。我在我的 API 中设置了 cors,如下所示: app.use(cors({credentials: true, origin: true}));

在我的 react 应用程序中,我一直在使用 axios 来发送 get 和 post 请求,我在一个确实收到响应的组件中有一个这样的 get 请求:

isLoggedIn(){
        let isLogged = false;
        Fetch("http://localhost:4000/IsLogged")
        .then((results)=> {
            console.log(results)
            isLogged = results.data
        })
        .catch((err)   => console.log(err))
        this.setState({loggedIn: isLogged})
    }
    componentDidMount(){
        this.isLoggedIn();
    }

但是,当我尝试使用此代码接收用户详细信息时:

getUserDetails(){
    Fetch("http://localhost:4000/userDetails")
        .then((results)=> {console.log(results)})
        .catch((err)   => console.log(err))
  }
  componentDidMount(){
    this.getUserDetails()
  }

我在控制台中得到这个响应:

Access to XMLHttpRequest at 'http://localhost:3000/login' (redirected from 'http://localhost:4000/userDetails') from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

这是服务器端代码:

app.get("/userDetails",(req,res)=>{
  //if there is no userID associated with the session then the user hasnt logged in, redirect to login
  console.log(req.session.UserID)
  if(!req.session.UserID) {
    res.redirect("http://localhost:3000/login")
  }else{
    let userID = req.session.UserID
    connection.query("SELECT * FROM `users` WHERE id =" + userID)
    .then((rows) => res.send(rows[0]))
    .catch((err) => console.error(err))
  }
})

这可能是一些愚蠢的事情,所以如果这真的很基本,我很抱歉,任何关于此的阅读链接也会很棒。感谢您提供的任何帮助!

【问题讨论】:

  • 为什么错误消息说,“在http://localhost:3000/login(重定向自http://localhost:4000/userDetails)” - 您在端口 4000 上运行的 API 将重定向到前端的业务在端口 3000 上以…开头?
  • 它只是检查您是否尝试在未登录的情况下访问用户仪表板,如果您输入localhost:4000/userDetails,则重定向到登录页面
  • 你说这是一个 API,为什么有人会尝试通过调用 API URL 来访问用户仪表板?如果您的任何 :4000 URL 在没有正确凭据的情况下被调用,您的 API 应该通过发出适当的错误代码来处理它,而不是通过重定向到 前端!你在这里以一种毫无意义的方式混合了两种不同的东西。

标签: javascript reactjs axios


【解决方案1】:

这不是CORS 的东西。

您不能从后端重定向。换句话说,如果用户没有登录你的 api 应该返回一个 Not-authorized 响应。然后在您的前端,您应该路由到登录页面。

问题是您试图从后端访问 localhost:3000 (前端)。并且为端口 4000 或后端设置了 cors。

 console.log(req.session.UserID)
 if(!req.session.UserID) {
     //Your should return unauthorized response then check the response at the front end react axios response.
       res.json({
         status: 401,
         message: "Action Not Allowed",
         name: "AUTHORIZATION_ERROR"
       });
     //res.redirect("http://localhost:3000/login")
  }else{ ....


getUserDetails(){
Fetch("http://localhost:4000/userDetails")
    .then((results)=> {
        if(results.data.status == 401) {
              // then change the page.
         }
     })
    .catch((err)   => console.log(err))
}

【讨论】:

    【解决方案2】:

    在您拥有app.use(cors({credentials: true, origin: true})); 的文件中尝试添加:

    app.use(function(req, res, next) {
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
      next();
    });
    

    然后在你的路线中,通过下一个,像这样:

    app.get("/userDetails",(req,res,next)=>{
      //if there is no userID associated with the session then the user hasnt logged in, redirect to login
      console.log(req.session.UserID)
      if(!req.session.UserID) {
        res.redirect("http://localhost:3000/login")
      }else{
        let userID = req.session.UserID
        connection.query("SELECT * FROM `users` WHERE id =" + userID)
        .then((rows) => res.send(rows[0]))
        .catch((err) => console.error(err))
      }
    })
    

    让我知道它是否有效! P.S - 您使用的是哪个服务器端处理?提供,以便我们更好地帮助您!

    【讨论】:

    • 不,我添加了所有内容并重新启动了服务器,但仍然没有运气!
    • 您使用的是哪个服务器端处理?
    • 我正在使用 Express.js 是我用来处理我的 HTTP 请求的包
    • @MiguelCruz Man,这根本不是cors 的问题。
    • 是的,我可以看到。你完全正确。我没有注意港口。他只需要使用 4000 而不是 3000。但我会留下我的答案,以防有人遇到 cors 问题。
    【解决方案3】:

    您可以在节点服务器中使用以下中间件来修改传入请求。只要把它放在你的溃败之前,它就可以解决问题..

    app.use(function(req, res, next) {
      // Website you wish to allow to connect
      res.setHeader("Access-Control-Allow-Origin", "*");
      // Request methods you wish to allow
      res.setHeader(
        "Access-Control-Allow-Methods",
        "GET, POST, OPTIONS, PUT, PATCH, DELETE"
      );
      // Request headers you wish to allow
      res.setHeader(
        "Access-Control-Allow-Headers",
        "X-Requested-With,content-type"
      );
      // Set to true if you need the website to include cookies in the requests sent
      // to the API (e.g. in case you use sessions)
      res.setHeader("Access-Control-Allow-Credentials", true);
      // Pass to next layer of middleware
      next();
    });

    【讨论】:

    • 我也试过你的sn-p,还是不行,感谢cmets!
    猜你喜欢
    • 2015-04-17
    • 1970-01-01
    • 2016-11-23
    • 2012-12-20
    • 2018-09-24
    • 2020-12-25
    • 2019-08-01
    • 2016-05-05
    • 2017-07-22
    相关资源
    最近更新 更多