簡體   English   中英

XMLHttpRequest 錯誤 flutter web [啟用 CORS AWS API 網關]

[英]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";

我的應用程序僅使用GETHEAD ,因此您可能需要根據您的情況添加其他方法。

另請參閱:如何在 Apache 和 Nginx 中啟用 CORS?

我在后端使用 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

第二步:代碼行在此處輸入圖像描述

第 3 步然后通過以下步驟添加獲取 ip 在此處輸入圖像描述

Step 4 在app/android studio中添加在此處輸入圖像描述

這對我有用:

Step 1: npm install cors

安裝cors后定義

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

添加中間件啟用 cors

Step 3: app.use(cors())

忘記了 https 端點

在這個“XMLHttpRequest 錯誤”上花了 3 個小時......

對於許多開發人員來說可能是顯而易見的,但在我的情況下,我正在從 https 向 http 端點發出 CORS 請求。

如果你想讓它工作,除了其他答案(啟用 CORS,允許 origin *,向請求添加標頭)之外,擁有一個 https endpoint 是至關重要的


使它工作的完整代碼(使用 nginx,節點快遞服務器和 flutter 網絡):

服務器


Nginx

在 nginx 配置文件/etc/nginx/sites-available/mywebsite.comlocation添加這些行:

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

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 添加到后端后,它終於可以正常工作了。

嘗試

  • 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM