带URL查询字符串参数时仅触发CORS错误的原因排查
问题描述
我在AWS API Gateway上配置了一个带非必填URL查询字符串参数的GET资源方法,已启用CORS且OPTIONS方法可正常用于其他授权API调用。当前端不带该参数调用GET方法时一切正常,通过API Gateway控制台带参数测试也无问题,但前端带参数调用时却出现CORS错误:
Access to fetch at 'myAPIURL' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
该API的其他信息:
- 用于触发Lambda函数获取DynamoDB记录
- 其他方法无CORS错误,且均未使用字符串参数
- 部分使用路径参数的方法可正常工作
- 采用Cognito进行授权
前端调用代码如下:
fetchInvoices(strParam){ const returnedData = null; const url = invokeURL + encodeURIComponent("invoicess?invYear=" + strParam); fetch(url, { headers: { "Authorization": token } }) .then(response => { return response.json() }) .then(jsonData => { returnedData = jsonData; }) .catch(e => { console.log(e) }) return returnedData }
原因分析与解决办法
1. 前端URL拼接错误(核心问题)
你当前的代码用encodeURIComponent把整个"invoicess?invYear=" + strParam都编码了,这会把?和=这些URL关键符号也转义,导致API Gateway无法正确识别路径和查询参数,返回4xx类错误(比如404)。浏览器在请求失败时,会把这类错误包装成CORS错误提示,实际根源是URL格式不对。
正确的做法是只编码查询参数的值,而非整个路径和参数串,同时修正异步返回数据的逻辑:
fetchInvoices(strParam){ // 仅对参数值进行编码,保留路径和参数分隔符 const url = `${invokeURL}invoicess?invYear=${encodeURIComponent(strParam)}`; // 异步函数需返回Promise,才能让调用方获取到数据 return fetch(url, { headers: { "Authorization": token } }) .then(response => { if (!response.ok) { throw new Error(`请求失败,状态码:${response.status}`); } return response.json(); }) .catch(e => { console.log(e); throw e; // 抛出错误让调用方处理 }); }
2. 其他排查点(若修正URL后仍有问题)
- 确认API Gateway中该GET方法已添加
invYear作为非必填查询参数,否则API Gateway可能因收到未定义参数而拒绝请求。 - 查看Lambda函数的CloudWatch日志,检查是否因参数格式不符合预期导致返回5xx错误,这类错误也会被浏览器包装成CORS错误。
- 验证该GET方法的CORS配置,确保
Access-Control-Allow-Headers包含Authorization,且Access-Control-Allow-Origin正确设置为http://localhost:8080(生产环境不建议用*)。
内容的提问来源于stack exchange,提问作者Yolo_chicken
相关产品推荐
相关产品推荐

