因為需要, 在 Apps Script 上以氣象局 API 包裝了查詢指定縣市一週天氣的 API, 發現透過瀏覽器的網頁存取時會被擋, 原來又是 CORS 的關係。JavaScript 部分如下: ```javascript async function getTemp() { let city = '新北市'; let url = 'https://script.google.com/macros/s/AKfycbyXm4MYMtjIrjxi98luIq2qVbp1GQXtupov8r66bAN273Wg7jlDNLNTK16ZqCPUfEpr/exec'; try { let res = await fetch(url, { method: "POST", headers: {'Content-Type': 'applicaion/json'}, body: JSON.stringify({ city: city }) }); return await res.text(); } catch (error) { console.log(error); } } ``` 由於指定了內容類型為 JSON, 被瀏覽器認定是[非簡單請求](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/CORS#%E7%B0%A1%E5%96%AE%E8%AB%8B%E6%B1%82), 會啟動[預檢 (preflight) 程序](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/CORS#%E9%A0%90%E6%AA%A2%E8%AB%8B%E6%B1%82), 也就是發送 OPTIONS 請求詢問伺服端是否允許跨網域存取, 不過 Apps Script 的網頁應用並不接受 OPTIONS 請求, 回應 [405 錯誤](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status/405), 導致存取失敗: ![image](https://hackmd.io/_uploads/SyacLq9O6.png) 使用 curl 測試如下: ```shell # curl -i -X OPTIONS 'https://script.google.com/macros/s/AKfycbyXm4MYMtjIrjxi98luIq2qVbp1GQXtupov8r66bAN273Wg7jlDNLNTK16ZqCPUfEpr/exec' HTTP/1.1 405 Method Not Allowed Content-Type: text/html; charset=UTF-8 Date: Tue, 09 Jan 2024 09:48:07 GMT Expires: Tue, 09 Jan 2024 09:48:07 GMT Cache-Control: private, max-age=0 X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Content-Security-Policy: frame-ancestors 'self' X-XSS-Protection: 1; mode=block Server: GSE Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 Accept-Ranges: none Vary: Accept-Encoding Transfer-Encoding: chunked <HTML> <HEAD> <TITLE>Method Not Allowed</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF" TEXT="#000000"> <H1>Method Not Allowed</H1> <H2>Error 405</H2> </BODY> </HTML> ``` 只要改用 GET, 或是把 JavaScript 中請求內容類型改成 "text/plain", 甚至把內容類型的表頭拿叫, 就可以變成簡單請求, 避開預檢程序正確存取了。