JS / 以Google表單為基礎,製作客製化Html表單 2 以自架PHP主機為中繼

在細講程式碼之前,先說說客製化表單遇到的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表單也能夠顯示傳回的畫面了