在細講程式碼之前,先說說客製化表單遇到的cors問題
備註:cors簡單的說就是瀏覽器的安全性功能,限制跨域請求,避免有人透過其他網頁/主機來取得主機的資料
雖然會有cors錯誤,表單資料還是會傳出,但就不會收到伺服器傳回來的資料
表單在設計的時候,通常會設定readyState ===4 && status ===200
也就是HTTP Request執行成功( readyState,4),並且伺服器也正確回應( status,200)
程式要接著執行的內容,例如呈現伺服器回傳資料,或者其他操作
如果有cors錯誤,瀏覽器就不會顯示伺服器的回應以及回傳的資料
fetch可以設定mode: “no-cors”,讓瀏覽器不處理cors問題
但這樣就不會得到伺服器的回應,status 會是 0
但也因為如此就可以透過程式判斷,如果 status ==0,程式要執行的程序
讓程式不會因為得不到回應而無法設計後續的流程操作,這也是前一篇的處理方式
由於cors是瀏覽器的安全性功能,如果能夠自己架設主機的話,就可以設定可以跨域的網址
將自架主機作為中繼來接收傳來的資料,再發出HTTP Request將資料傳出
而主機之間的溝通是沒有cors問題,這種方式就可以避免cors錯誤
備註:因為是透過codePen發出請求,所以跟自架主機之間也是非同源,會有cors錯誤
跟直接從codePen發出請求的情況一樣
但是自架主機可以透過增加允許網域來處理這個問題
如果不用codePen,將網頁移到自架主機內,也不會有cors錯誤
這個就跟一般的瀏覽情況一樣
這裡是用xampp架設主機,以PHP作為伺服器操作的網頁程式
修改Apache的設定檔httpd.conf,加入可以跨域的網址
因為是在codePen測試,所以加入codePen實際發出請求的網域https://cdpn.io
原本的程式碼fetch的目標網址要改成這個自架主機的php所在的網址
由於google表單的欄位名稱都是entry.開頭,「.」要改成「_」才能取得資料
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?php $man = $_POST['entry_1828511335'];// . 改成 _ $ser = $_POST['entry_1917575556']; $mail = $_POST['entry_63664357']; $member = $_POST['entry_2045497083']; $question = $_POST['entry_155393842']; $goal = $_POST['entry_2099781610']; $context = $_POST['entry_2095623174']; $subAll = $_POST['entry_1309221649']; $data = array( 'entry.1828511335' => $man, 'entry.1917575556' => $ser, 'entry.63664357' => $mail, 'entry.2045497083' => $member, 'entry.155393842' => $question, 'entry.2099781610' =>$goal, 'entry.2095623174' => $context, 'entry.1309221649' => $subAll ); $POST_DATA = http_build_query($data); $curl = curl_init(); /* ganti http://example.com dengan external server Anda. */ curl_setopt($curl, CURLOPT_URL,'https://docs.google.com/forms/d/e/********************************************************/formResponse'); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $POST_DATA); $response = curl_exec($curl); curl_close ($curl); // echo $response; ?> |
其他的部分就跟javascritp類似,只是透過php的方式來處理資料以及發出HTTP Request
在原始的google表單送出資料之後,網頁顯示已經收到回覆的畫面
所以在#335-339設計了接收傳回的html,並將資料寫入id名稱為doneShow的div之中
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
fetch(url, { method: "POST", headers: headers, //mode: "no-cors", //******************************重要 因為預期會有cors error ,這樣才會取得status = 0 body: body }) .then((response) => { console.log("response.status =", response.status); return response.text(); //console.log(response.text()); }).then(html => { console.log(html); document.getElementById("formOne").style.display="none"; document.getElementById("doneShow").style.display="block"; // Initialize the DOM parser document.getElementById("doneShow").innerHTML=html; }) |
這樣客製的Html表單也能夠顯示傳回的畫面了