Zeit(Vercel)现在,由于CORS,无服务器身份验证请求失败

浏览器发出PATCH标头和{{1}的POST / PUT / Authorization请求时,我无法正确处理CORS问题}}(在浏览器外部和Bearer token请求中正常工作)在Zeit Now serverless中。

如果有帮助,我正在使用Auth0作为授权方。


这是我的GET标头部分,我尝试了很多组合,但都没有从浏览器中获得成功。

Zeit(Vercel)现在,由于CORS,无服务器身份验证请求失败


  1. 我尝试使用npm now.json软件包失败
  2. 试图在cors中添加routes
  3. 使用now.json
  4. 在无服务器功能的顶部尝试设置标头
  5. 还尝试通过以下方式手动处理res.addHeader()请求:

Zeit(Vercel)现在,由于CORS,无服务器身份验证请求失败

最后,这是我得到的错误

OPTIONS

不确定我的错或如何正确处理此问题。

rmb001 回答:Zeit(Vercel)现在,由于CORS,无服务器身份验证请求失败

我能够使用micro-cors绕过此问题。

我检查了its code,与我尝试通过手动使用res.setHeader来自己做的事情没什么不同,很可能是我猜不到的东西。

尽管如此,我不明白为什么now.json中的设置无法正常工作,我需要在无服务器功能中手动执行此操作。

无论如何,万一有人找到这篇文章,我最终会得到这样的东西:

import micro from "micro-cors";

function MyApi(req,res) {
  if (req.method === "OPTIONS") {
    return res.status(200).end();
  }
  // handling other requests normally after this
}

const cors = micro();

export default cors(MyApi);

我可能会再尝试使用一种自行编写的解决方案,以便更好地了解出了什么问题,并且还因为我不想额外依赖。

如果我这样做,将更新此答案。


编辑:在更深入地检查之后,我发现另一个问题是库express-jwtres解析失败时专门更改了jwt对象。 / p>

我有一个小型的中间件,它通过这样做破坏了一切:

await authValidateMiddleware(req,res);

await失败时,它中断了一切,因为express-jwt在不知不觉中更改了res标头(设置错误),然后我尝试设置了res标头手动手动尝试自己正确处理错误,因此引发有关“多次更改res标头”的问题。

,

我遇到了类似的问题,并且通过将标题添加到路由中来解决了该问题,如下所示:

"routes": [
    {
      "src": ".*","methods": ["GET","POST","OPTIONS"],"headers": {
        "Access-Control-Allow-Origin": "*","Access-Control-Allow-Headers": "Origin,X-Requested-With,Content-Type,Accept","Access-Control-Allow-Credentials": "true"
      },"dest": "index.js","continue": true
    },{
      "src": "/user/login","methods": ["POST"],"dest": "index.js"
    }
  ]

记住要添加continue: true

https://github.com/super-h-alt/zeit-now-cors-problems/blob/master/now.json

,

我处于几乎相同的情况。我在Vercel(Now)中有几个无服务器功能,我希望它们对任何来源的任何人都可用。我解决的方法类似于@illiteratewriter's answer

首先,我在项目的根目录中有以下now.json

{
  "routes": [
    {
      "src": "/api/(.*)",{
      "src": "/api/(.*)","methods": ["OPTIONS"],"dest": "/api/cors"
    }
  ]
}

这是两个路由配置的细分:

{
  "src": "/api/(.*)","headers": {
    "Access-Control-Allow-Origin": "*","Access-Control-Allow-Credentials": "true"
  },"continue": true
}
  • "src": "/api/(.*)"

匹配所有发送到/api/*的请求。

  • "headers": [...]

将CORS标头应用于该路由,表示允许使用CORS。

  • "continue": true

应用CORS标头后,继续寻找其他路线匹配项。这使我们可以将CORS标头应用于 all 路由,而不必按路由进行。例如,现在/api/auth/login/api/main/sub/resource都将应用CORS标头。

{
  "src": "/api/(.*)","dest": "/api/cors"
}

此配置的作用是拦截所有HTTP/OPTIONS请求(这是CORS飞行前检查),然后将它们重新路由到/api/cors处的特殊处理程序。

路由配置细分的最后一点将我们引向/api/cors.ts函数。该处理程序如下所示:

import {NowRequest,NowResponse} from '@now/node';

export default (req: NowRequest,res: NowResponse) => {
  return res.status(200).send();
}

此处理程序所做的基本上是接受CORS飞行前OPTIONS请求,并以200/OK对其进行响应,向客户表示“是的,我们对CORS业务开放。”

,

我对CORS和Vercel无服务器功能有很多类似的问题。

经过很多尝试→失败过程后,我才找到解决方案。


解决方案

tldr

最简单的解决方案,只需使用micro-cors

并具有类似的实现;

import { NowRequest,NowResponse } from '@now/node';
import microCors from 'micro-cors';

const cors = microCors();

const handler = (request: NowRequest,response: NowResponse): NowResponse => {
  if (request.method === 'OPTIONS') {
    return response.status(200).send('ok');
  }

  // handle incoming request as usual
};

export default cors(handler);

版本较长,但没有任何新的依赖项

使用vercel.json处理请求标头

vercel.json

{
  "headers": [
    {
      "source": "/.*","headers": [
        {
          "key": "Access-Control-Allow-Origin","value": "*"
        },{
          "key": "Access-Control-Allow-Headers","value": "X-Requested-With,Access-Control-Allow-Origin,X-HTTP-Method-Override,Authorization,Accept"
        },{
          "key": "Access-Control-Allow-Credentials","value": "true"
        }
      ]
    }
  ]
}

自我尝试后,上述设置中有 2个重要的键

  1. 您必须将Access-Control-Allow-Origin设置为所需的内容
  2. Access-Control-Allow-Headers中,您必须在其值中包括 Access-Control-Allow-Origin

然后在无服务器功能中,您仍然还需要处理pre-flight request

/api/index.ts

const handler = (request: NowRequest,response: NowResponse): NowResponse => {
  if (request.method === 'OPTIONS') {
    return response.status(200).send('ok');
  }

  // handle incoming request as usual
};

我建议通读micro-cors中的代码,它是非常简单的代码,您可以在几分钟之内理解它的作用,这使我不必担心将其添加到我的依赖项中。

,

接受的答案对我不起作用。但是,现在vercel似乎具有updated their advice,其示例代码为:

const allowCors = fn => async (req,res) => {
  res.setHeader('Access-Control-Allow-Credentials',true)
  res.setHeader('Access-Control-Allow-Origin','*')
  // another option
  // res.setHeader('Access-Control-Allow-Origin',req.headers.origin);
  res.setHeader('Access-Control-Allow-Methods','GET,OPTIONS')
  res.setHeader(
    'Access-Control-Allow-Headers','X-CSRF-Token,Accept,Accept-Version,Content-Length,Content-MD5,Date,X-Api-Version'
  )
  if (req.method === 'OPTIONS') {
    res.status(200).end()
    return
  }
  return await fn(req,res)
}

const handler = (req,res) => {
  const d = new Date()
  res.end(d.toString())
}

module.exports = allowCors(handler)

值得一提的是,我不确定res.endres.send之间的区别,但是为了将响应实际吸收到前端(响应),我将handler函数更改为:

const handler = (req,res) => {
        const d = {data: "Hello World"}; 
        res.send(d)
}

这使我能够以以下方式摄取React:

function getAPIHelloWorld () {
    let connectStr = "/api"
    fetch(connectStr)
        .then(response => response.json())
        .then(response => {console.log(response.data)})
        .catch(err => console.error(err))
}
本文链接:https://www.f2er.com/2441599.html

大家都在问