2021年12月29日 星期三

Apps Script : has been blocked by CORS policy

2021年12月29日 星期三

這幾天在試著以 POST 的方式將圖片資料丟給 Google Apps Script 後,再利用別的網站來進行 QR Code 解碼。不過,一直出現底下的錯誤訊息:


Access to XMLHttpRequest at 'https://script.google.com/macros/s/....../exec' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.


這裡面最關鍵的字當然是「CORS」,很明顯的, Google Apps Script 的服務主機並沒有送出有關 CORS 的表頭,以致無法跨域取得處理的結果。可以參考這裡的詳細說明:

之前在寫 HTML5 筆順練習程式時,為了擷取教育部的筆順資料的 XML 檔案,也是花了好多時間研究如何克服 CORS 的障礙,後來是利用 Google Apps Script 來抓教育部網站中的 XML 檔案,然後再以 JSON 格式回傳給 callback 的程序,是的!關鍵在「JSON 格式」!不過那時是使用 GET 的方式。而這一回因為傳圖形資料,資料量大,只能使用 POST 的方式,又卡關了!

無論使用 XMLHttpRequest 或是較新的 fetch 來進行 POST,Google Apps Script 端的程式,當然是得以 JSON 格式來包裝,例如我要回傳的資料是「{status: status, "qrcode": result}」,就在最後加上:


return ContentService.createTextOutput(JSON.stringify({status: status, "qrcode": result})).setMimeType(ContentService.MimeType.JSON);


此部分在之前寫 HTML5 筆順練習程式時就有經驗。那利用  XMLHttpRequest 或 fetch  來進行 POST 傳所需要的參數資料時,為什麼還是出現了 CORS 的問題?

關鍵還是在「JSON 格式」,如果想避免出現 CORS 的錯誤訊息,就把要傳給 Google Apps Script 的資料,以「JSON 格式」的字串包裝。例如我想傳的圖片資料,參數名稱為「f」,而圖形資料已經轉為「DataURL」的字串,放到 base64 的變數中了,就這樣包裝:


JSON.stringify({'f':base64})


將這個包裝過的參數資料給  XMLHttpRequest 或 fetch  來進行 POST ,再搭配 Google Apps Script 也是以「JSON 格式」回傳資料。應該就可以避免 CORS 的錯誤了。

另外,在 Google Apps Script 的 doPost 序程裡如何取得由 POST 傳進來的參數內容呢?


function doPost(request) {
  var content = JSON.parse(request.postData.contents);
  var f = content.f;
  ......
}


client 端的資料被放到 postData.contents 中,而且是一個字串,所以先用 JSON.parse 將字串轉為物件,這樣才方便取用。

總之,為了能跨域傳資料,client 端或是 server 端,通通以 JSON 來交換資料就可以避免走冤枉路了。


沒有留言:

張貼留言

 
雄::gsyan © 2009. Design by Pocket