[英]XMLHttpRequest error in flutter web [Enabling CORS AWS API gateway]
注意:事实证明,这与 flutter 无关,而与我将 API 网关设置为 Lambda 代理这一事实有关
我试图从 Flutter web 应用程序访问 API 端点,每次它出错并给我以下错误。
获取传感器数据时出错:DioError [DioErrorType.RESPONSE]: XMLHttpRequest 错误。
我知道这里有几个关于 SO 的问题(比如这个和这个)讨论这个问题,解决方案似乎是在服务器端启用 CORS 支持。 我正在使用 AWS API 网关构建 API,我按照这些说明从我的 API 启用 CORS 支持。这是我在 API 网关控制台中的 CORS 设置。
“Access-Control-Allow-headers”中的文本是
'内容类型、X-Amz-日期、授权、X-Api-密钥、X-Amz-安全令牌'
在 API 网关上启用 CORS 似乎没有帮助,当我尝试点击 API 时,我的 flutter web 应用程序仍然出现相同的错误。
有趣的是,如果我从 chrome 中点击 API(即在浏览器上粘贴 API URL 并点击回车),API 工作得很好。 只有当我尝试从 flutter web 应用程序点击 API 时,它才会失败。
问题:如何在我的 API 网关中启用 CORS 支持,以便我的 flutter web 应用程序可以使用 API?
这对我有用,我在 lambda function 上添加了以下 header
return {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*", // Required for CORS support to work
"Access-Control-Allow-Credentials": true, // Required for cookies, authorization headers with HTTPS
"Access-Control-Allow-Headers": "Origin,Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,locale",
"Access-Control-Allow-Methods": "POST, OPTIONS"
},
body: JSON.stringify(item)
};
我的服务器使用的是 nginx,所以我通过将以下两行添加到我的 API 服务器的启用站点的配置文件的服务器块中解决了这个问题:
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, HEAD";
我的应用程序仅使用GET
和HEAD
,因此您可能需要根据您的情况添加其他方法。
我在后端使用 Nodejs。 当我从 Dio 发送一个 post 请求时,出现了这个错误: “XMLHttpRequest error.”。
此错误背后的原因:假设您的 flutter 在 localhost:5500 上运行,而 nodejs 服务器在 localhost:3000 上运行。 因此,您的浏览器无法处理请求,因为它们在不同的端口上运行。 那就是我们使用CORS或者Proxies来解决这些问题。
请记住,这是一个主要与您的浏览器相关的问题。 如果您将使用 postman 并发送相同的请求,您会发现一切正常。
为了解决这个问题:我安装了一个名为 CORS 的 NPM Package。
npm i cors
然后,开始使用它......
const cors = require("cors");
app.use(cors());
通过这样做,您的错误将得到解决。 而且您不需要再添加任何东西。
在cpanel中启用 CORS 以在您的主机帐户中启用 CORS。 您可以启用它,在您的托管帐户的.htaccess文件中添加以下行。
<IfModule mod_headers. ...
Header set Access-Control-Allow-Origin "*"
</IfModule>
这是您的后端和前端的问题,特别是如果您需要添加身份验证 header。您需要做两件事。 在您的后端允许 cors 并指定您在前端发送 json。
前端
var request = await http.post(
Uri.parse(url),
headers: {
"auth-token": idToken, // whatever headers you need
"content-type": "application/json" // This preventes empty response body
},
body: jsonEncode(<String, String>{
'name': name,
'email': email,
})
后端
const cors = require('cors');
app.use(cors({
origin: '*',
allowedHeaders: 'X-Requested-With, Content-Type, auth-token',
}));
app.use("/api/user", authRoute); // this is the endpoint yoou're calling with your Flutter Web frontend
如果您无权访问服务器端,最好设置一个反向代理。 我使用了最低配置的 nginx 代理,在 docker 容器中运行。
docker-compose.yml:
version : '3'
services :
nginx:
image: nginx:latest
container_name: nginx_container
ports:
- 3000:3000
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
nginx.conf:
events {
}
http {
server {
listen 3000;
location / {
proxy_pass http://original_address_and_port/;
}
}
}
然后,您可以使用 http://localhost:3000 作为 API 基础进行开发,nginx 将发送请求到原始地址和端口。
使用这些步骤解决了问题....在我的例子中:
我在后端使用 Nodejs。 当我从 HTTP 发送一个 post 请求时,出现了这个错误:“XMLHttpRequest error.”。
1): 在节点依赖链接中安装它
npm 安装 cors
这对我有用:
Step 1: npm install cors
安装cors后定义
Step 2: const cors = require('cors')
添加中间件启用 cors
Step 3: app.use(cors())
在这个“XMLHttpRequest 错误”上花了 3 个小时......
对于许多开发人员来说可能是显而易见的,但在我的情况下,我正在从 https 向 http 端点发出 CORS 请求。
如果你想让它工作,除了其他答案(启用 CORS,允许 origin *,向请求添加标头)之外,拥有一个 https endpoint 是至关重要的。
使它工作的完整代码(使用 nginx,节点快递服务器和 flutter 网络):
在 nginx 配置文件/etc/nginx/sites-available/mywebsite.com
的location
添加这些行:
location / {
#ALLOW CORS#
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
#END OF ALLOW CORS#
try_files $uri $uri/ =404;
索引.js
const app = express()
const cors = require('cors');
app.use(cors());
// usual stuff
(需要安装cors: npm install cors
在后台目录安装cors)
服务器.js
const app = require('./index')
const fs = require('fs')
const https = require('https')
const port = process.env.PORT || 3000;
var options = {
key: fs.readFileSync('./certs/privkey.pem'),
cert: fs.readFileSync('./certs/fullchain.pem'),
};
var server = https.createServer(options, app).listen(port, function(){
console.log("Express server listening on port " + port);
});
Future<String> testRequest() async {
Uri uri =
Uri(scheme: 'https', port: 3000, host: 'mywebsite.com', path: 'folder'); // to reach this endpoint: 'https://mywebsite.com:3000/folder'
var headers = {
"Access-Control-Allow-Origin": "*",
'Content-Type': 'application/json',
'Accept': '*/*'
};
try {
http.Response response = await http.get(uri, headers: headers);
return response.body;
} catch (e) {
return inspect(e).toString();
}
}
注意:端点有一个自定义路径
因此,在将证书和 https 添加到后端后,它终于可以正常工作了。
尝试
Go 到 flutter\bin\cache 并移除 flutter_tools.stamp 文件
Go 到 flutter\packages\flutter_tools\lib\src\web 打开文件 chrome.dart 并编辑它 在 '--disable-extensions' 行旁边添加 '--disable-web-security'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.