Javascript Zeit(Vercel)现在无服务器身份验证请求因CORS而失败
在执行Javascript Zeit(Vercel)现在无服务器身份验证请求因CORS而失败,javascript,cors,authorization,serverless,vercel,Javascript,Cors,Authorization,Serverless,Vercel,在执行修补程序/发布/放入请求时,我无法正确处理CORS问题,该请求来自浏览器,发送带有承载令牌的授权头(这在浏览器外部和获取请求时正常工作) 如果有帮助的话,我将使用授权端 这是我的now.jsonheaders部分,我尝试了很多组合,但都没有从浏览器中成功 我尝试使用npmcors包,但没有成功 尝试在now.json中添加routes 尝试使用res.addHeader() 还尝试手动处理选项请求,执行以下操作: 最后,这是我得到的错误 Access to XMLHttpReque
修补程序
/发布
/放入
请求时,我无法正确处理CORS问题,该请求来自浏览器,发送带有承载令牌的授权
头(这在浏览器外部和获取
请求时正常工作)
如果有帮助的话,我将使用授权端
这是我的now.json
headers部分,我尝试了很多组合,但都没有从浏览器中成功
我尝试使用npmcors
包,但没有成功
尝试在now.json中添加routes
尝试使用res.addHeader()
还尝试手动处理选项
请求,执行以下操作:
最后,这是我得到的错误
Access to XMLHttpRequest at 'https://api.example.org/api/users' from origin 'https://example.org' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
不知道我错了什么,也不知道如何正确处理。我可以通过使用绕过此问题
我检查了一下,与我手动使用res.setHeader
尝试做的事情没有太大区别,我猜可能遗漏了什么
然而,我不明白为什么now.json
中的设置不能正常工作,我需要在无服务器函数中手动执行此操作
不管怎么说,万一有人找到了这篇文章,我最终得到了这样的结果:
从“micro-cors”导入micro;
函数MyApi(req,res){
如果(请求方法==“选项”){
返回res.status(200.end();
}
//在此之后正常处理其他请求
}
const cors=micro();
导出默认cors(MyApi);
我可能会用自己编写的解决方案再试一次,以便更好地了解出了什么问题,也因为我不想要额外的依赖关系
如果我这样做,将更新此答案
编辑:在深入检查之后,我发现另一个问题是库express jwt
在jwt
解析失败时专门更改res
对象
我有一个小型中间件,它通过以下操作打破了一切:
wait authValidateMiddlware(req,res);
当wait
失败时,由于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"
}
]
请记住添加继续:true
我当时的情况也差不多。我在Vercel(现在)中有两个无服务器功能,我希望任何人都可以使用它们。我解决问题的方法类似于
首先,我的项目根目录中有以下now.json
:
{
"routes": [
{
"src": "/api/(.*)",
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept",
"Access-Control-Allow-Credentials": "true"
},
"continue": true
},
{
"src": "/api/(.*)",
"methods": ["OPTIONS"],
"dest": "/api/cors"
}
]
}
以下是两种路线配置的细分:
{
"src": "/api/(.*)",
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept",
"Access-Control-Allow-Credentials": "true"
},
"continue": true
}
“src”:/api/(.*)
匹配任何转到/api/*
的请求
“标题”:[…]
将CORS标头应用于路由,表示允许CORS
“继续”:true
在应用CORS头之后,继续查找其他路由匹配项。这允许我们将CORS头应用于所有路由,而不必为每个路由应用。例如,现在/api/auth/login
和/api/main/sub/resource
都将应用CORS头
{
"src": "/api/(.*)",
"methods": ["OPTIONS"],
"dest": "/api/cors"
}
此配置的作用是拦截所有HTTP/OPTIONS
请求,即CORS飞行前检查,并将它们重新路由到/api/CORS
的特殊处理程序
routes配置分解的最后一点将我们引向/api/cors.ts
函数。处理程序如下所示:
从'@now/node'导入{NowRequest,NowResponse};
导出默认值(请求:NowRequest,响应:NowResponse)=>{
返回res.status(200.send();
}
该处理程序所做的基本上是接受CORS飞行前选项
请求,并以200/OK
对其作出响应,向客户表示“是的,我们对CORS业务开放。”我对CORS和Vercel无服务器功能有类似的问题
经过大量的尝试→ 失败的过程我刚刚找到了解决方案
解决
太长,读不下去了
最简单的解决方案,就是使用
并有一个类似的实现
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, Content-Type, Authorization, Accept"
},
{
"key": "Access-Control-Allow-Credentials",
"value": "true"
}
]
}
]
}
自我尝试后,在上述设置中有两个重要键
您必须根据需要设置访问控制允许原点
在Access Control Allow Headers
中,必须在其值中包含Access Control Allow Origin
然后在无服务器函数中,还需要处理
/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
};
我建议阅读中的代码,这是一个非常简单的代码,您可以在几分钟内理解它将做什么,这使我不担心将其添加到依赖项中。接受的答案对我不起作用。但是vercel现在似乎有了,他们的示例代码是:
const allowCors=fn=>async(req,res)=>{
res.setHeader('Access-Control-Allow-Credentials',true)
res.setHeader('Access-Control-Allow-Origin','*'))
//另一种选择
//res.setHeader('Access-Control-Allow-Origin',req.headers.Origin);
res.setHeader('Access-Control-Allow-Methods','GET,OPTIONS')