flutter web中的XMLHttpRequest错误[启用CORS AWS API网关]

c9qzyr3d  于 2022-11-17  发布在  Flutter
关注(0)|答案(9)|浏览(224)

注意:事实证明,这与flutter无关,而是因为我将API网关设置为Lambda代理

我试图从Flutter Web应用程序中命中一个API端点,每次它都会出错,并给我以下错误。
获取传感器数据时出错:DioError [DioError类型.响应]:XMLHttpRequest错误。
我知道这里有一些关于SO的问题(如thisthis)讨论这个问题,解决方案似乎是在服务器端启用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并按Enter键),API工作得很好。只有当我试图从flutter Web应用点击API时,它才会失败。
问题:如何在API网关中启用CORS支持,以便flutter Web应用程序可以使用API?

aiazj4mn

aiazj4mn1#

这对我很有效,我在lambda函数上添加了下面的标题

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)
};
ruoxqz4g

ruoxqz4g2#

我的服务器使用的是nginx,因此我通过在API服务器的启用站点的配置文件的服务器块中添加以下两行代码来解决这个问题:

add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, HEAD";

我的应用程序只使用GETHEAD,因此您可能需要根据您的情况添加其他方法。
另请参阅:How to Enable CORS in Apache and Nginx?

lfapxunr

lfapxunr3#

我使用Nodejs作为我的后端。当我从Dio发送一个post请求时,出现了这个错误:“XMLHttpRequest错误。"。

**出现此错误的原因:**假设您的flutter运行在localhost:5500和localhost:3000上的nodejs服务器上。因此,您的浏览器无法处理请求,因为它们运行在不同的端口上。这就是我们使用CORS或代理来解决这些问题。

记住,这是一个主要与您的浏览器有关的问题。如果您将使用postman并发送相同的请求,您会发现一切都在工作。

**为了解决这个问题:**我安装了一个名为CORS的NPM包。

npm i  cors

然后,开始使用它....

const cors = require("cors");
app.use(cors());

只要这样做,你的错误就会得到解决,而且你不需要再添加任何东西。

vhmi4jdf

vhmi4jdf4#

cpanel中启用CORS以在您的主机帐户中启用CORS。您可以在主机帐户的**.htaccess**文件中添加以下行来启用它。

<IfModule mod_headers. ...
Header set Access-Control-Allow-Origin "*"
</IfModule>
dgenwo3n

dgenwo3n5#

这是后端和前端都存在的问题,特别是当你需要添加一个认证头时。你需要做两件事。在你的后端允许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
vfh0ocws

vfh0ocws6#

如果你没有访问服务器端的权限,最好设置一个反向代理。我使用了一个最小配置的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将发送请求到原始地址和端口。

cbwuti44

cbwuti447#

使用这些步骤解决了问题....在我的案例中:
我在后台使用Nodejs。当我从HTTP发送一个post请求时,出现了这个错误:“XMLHttpRequest错误"。
1):在节点依赖项link中安装此组件
npm安装代码
第2步:代码行x1c 0d1x
步骤3然后通过执行步骤

添加获取IP
步骤4添加应用程序/android studio

blpfk2vs

blpfk2vs8#

这对我很有效:

Step 1: npm install cors

安装cors后,对其进行定义

Step 2: const cors = require('cors')

添加中间件以启用cors

Step 3: app.use(cors())
dpiehjr4

dpiehjr49#

忘记使用https端点

在这个“XMLHttpRequest错误”上花了3个小时...
对于许多开发人员来说,这可能是显而易见的,但在我的情况下,我是从https向http端点发出CORS请求。
如果您想让它工作,除了其他答案(启用CORS、允许原点 *、向请求添加标题),拥有https端点至关重要。
完整的代码是什么使它工作(使用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

(you需要安装cors:后端目录中的npm install 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);
});

Flutter客户端应用程序:

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添加到后端后,它终于工作了。

相关问题