[Capacitor] App 往外的連線出現 Access-Control-Allow-Origin 錯誤?
接下來看到的問題是,app 裡往外打的 HTTP 請求,好像全都失敗了:
嗯… 用之前學到的 用 Safari 開發者工具找出 Cordova app 裡的 JavaScript 錯誤,
開 Safari 來看看模擬器裡的 Web app 有什麼問題吧~
在 Console 這邊看到了一堆 Access-Control-Allow-Origin 的錯誤:
統整一下大概就是這幾項:
- Origin capacitor://localhost is not allowed by Access-Control-Allow-Origin
- XMLHttpRequest cannot load https://book.tpml.edu.tw/logout due to access control checks
- Failed to load resource: Origin capacitor://localhost is not allowed by Access-Control-Allow-Origin
不過不管是哪一個,都是 Access-Control-Allow-Origin 造成的問題。
因為 Web app 事實是是用一個類瀏覽器在打開 Web app 的網頁,
當 Web app 又往外打 HTTP 請求 (像我的 app 是朝圖書館的網頁發出請求),
瀏覽器會覺得是 Web app 網站本身在對圖書館網站做跨站請求 (cross-site request),
而這個動作就會被 Access-Control-Allow-Origin 機制檢查,
確認圖書館網站可接受我的 Web app 網站的請求,才會送出。
這是瀏覽器的安全機制,因此 Cordova/Capacitor 這類 Web app 都會遭遇到問題。
在 Cordova 裡面,
我之前看到的是要利用像 cordova-plugin-advanced-http 這類 plugin,
來做出 Native 的 HTTP 請求,避開瀏覽器這層。
(不過我用起來又遇到了別的問題,像是 Cookie 的部分好像有些怪怪的…)
至於 Capacitor 裡要怎麼解決這個問題呢?
查了一下,這部分可以用 Capacitor Http API 來解決~
只要先在設定檔 capacitor.config.json 裡加上:
"plugins": { "CapacitorHttp": { "enabled": true } }
這樣就會開啟 Capacitor HTTP API 的功能,
它會修補 (patch) JavaScript 裡的 fetch API 和 XMLHttpRequest,
把它們改成用原生函式庫的方式發出 HTTP 請求,
一樣是避開了瀏覽器的 CORS 限制~
改好設定檔案,重新編譯執行 app,
已經可以正常往外連線了:
再用 Safari 觀察一下 Web app,
剛剛一堆 Access-Control-Allow-Origin 錯誤消失了,
都變成了 CapacitorHttp.request:
這樣子 CORS 的問題算是解決囉~