學習目標:了解透過 node.js 與瀏覽器發出 require 兩者之間的差異,以及使用瀏覽器傳送資料的方式。
在下面兩篇學習紀錄
了解網頁是透過從 client 端發出 request
後,sever 端回傳的一大堆 response
所構成,而當然不是要什麼都給,會透過 API(是一種交換資訊的管道)獲取限定的資料。
而瀏覽器其實只是一個程式
這邊在複習一下「從輸入網址後到看到網頁發生的事情」
- 瀏覽器接收到 user 輸入的資訊。
- 發出網路請求。
- DNS 開始將 url 解析成 IP 位置。
- 解析成功建立網路連線。
- server 端收到 request 後,回傳 response。
- 瀏覽器開始解析 response 檔案(就是 html 格式的檔案)。
- 在解析的過程中,如果遇到 CSS JS 圖片檔案等,就再發送 request ,server 回傳 response,反覆傳送。
- 發送完所有資源的 request 後開始下載資源。
- 進行渲染網頁。
上述的過程可以知道,response 的檔案不限定於某幾種,因此 json 格式也可以是個 response 檔案(例如:https://reqres.in/api/users)
node.js 與瀏覽器發 request 兩者之間的差異
在前幾週我們是透過 node.js 的 request 套件發出 request
,那這種方法跟使用瀏覽器兩者之間到底有什麼差異呢?
node.js :沒有任何限制與干擾,傳什麼就回什麼
「直接」將 request 傳送到 server 端,因此不會有任何限制與干擾。
瀏覽器:可能會阻止做某些事或加某些東西
「透過瀏覽器」將 request 傳送到 server 端,而瀏覽器基於安全性的考量會有某些限制與規範(同源政策、CORS等),可能會阻止做某些事或加某些東西(例如:增加瀏覽器的版本)。
因為這些差異導致我們在從瀏覽器發送 request 時有些規則需要學習
網頁前端傳資料到後端的方式
第一種 form
- 最陽春的方式,跟 JavaScript 一點關係都沒有,比較像是我要到這個頁面,那要帶什麼東西才能到這個頁面。
- 有
GET
及POST
兩種傳送方式,登入的話會用POST
GET
會將參數附加在網址後方,因此參數會外顯。POST
會將參數放在 request 內。 - 特性:會換頁並直接 random response。
- 缺點:每一次都要換頁
- 範例
<form action="/test" method="get"> <input type="text" name="username" id="username">姓名 <input type="submit" value="送出"></form>
按下送出後,會轉址到 action (範例是使用 GET
如果用 POST
一樣會轉址,
但不會顯示參數)
範例程式碼是發到 /test ,因為沒有這個檔案,所以頁面顯示找不到
如果是發送到 https://google.com 呢?
會跳轉到頁面並在後方加上參數。
第二種 AJAX
- 特性:將資料轉傳到 JavaScript ,就可以解決表單換頁的問題。
- 注意!html 的內容會是空的,因為我們是用 JavaScript 動態產生內容,因此對於搜尋引擎來說,會認為這個網頁是沒有內容的。
以下內容大部分取自文章: Huli 輕鬆理解 Ajax 與跨來源請求
全名 Asynchronous JavaScript and XML ,中文翻譯為「非同步的 JavaScript 與 XML 技術」。
了解這項技術前,首先要先知道什麼是「非同步的 JavaScript」。
什麼是同步?什麼是非同步
指的是 JavaScript 的「執行順序」
- 同步:會先等這行程式執行完畢並得到「結果」才繼續往下執行,確保執行順序。
- 非同步:執行後就不管他了,不等「結果」回來就繼續往下執行。
一般來說同步的 JavaScript 是非常合理的,但當牽涉到網路、交換資料就不能同日而論,我們將 reponse
替換結果,套入上述兩句話中:
- 同步:會先等這行程式執行完畢並得到「
reponse
」才繼續往下執行,確保執行順序。 - 非同步:執行後就不管他了,不等「
reponse
」回來就繼續往下執行。
當牽涉到網路、交換資料時,如果是「同步」的 JavaScript ,要等 reponse 回傳才會往下執行,代表說在這期間,點任何牽涉到 JavaScript 的東西都不會有任何反應,因為還在等前面的 Reponse 回來,老天鵝這不太對,人家會以為網站掛掉了吧!因此對於傳遞資料必須使用「非同步」的 JavaScript 。
那怎麼能知道 reponse 後結果(資料)要傳到哪執行呢?
這邊需要特別注意的是 「非同步的 Function 不能直接透過 return
把結果傳回來」,因為執行到 return
時,結果根本來還傳回來。
因此在 [第八週]DOM — 瀏覽器事件處理 學到的 callback function
就派上用場了
當非同步的操作完成時,就可以呼叫這個 Function,並且把結果帶進來執行。
實作 AJAX
const request = new XMLHttpRequest()request.onload = function() { if(request.status >= 200 && request.status < 400) { console.log(request.responseText); }else { console.log('err'); }}request.onerror = function() { console.log('error');}request.open('GET', 'https://reqres.in/api/users',true);request.send();
程式碼說明:
利用 AJAX送出一個 HTTP 請求,必須有三個步驟:
- 需要建立一個 XMLHttpRequest 物件
XMLHttpRequest
是一個 JavaScript 準備好的物件,主是要拿來發送request
與接收response
。const request = new XMLHttpRequest()
2. 開啟一個 url .open()
request.open(method, url[, async[, user[, password]]])
- 參數分別為 1⃣️Method 2⃣️URL 3⃣️同步 | 非同步 4⃣️使用者 5⃣️密碼
3. 發起一個請求 .send()
request.send()
這三個步驟就完成送出一個 HTTP 請求,但我們最主要的目的是拿到資料做事情,因此還要「監聽載入」拿到資料 .onload
有兩種寫法:
目標.onload = function(){ … }
目標.addEventListener(‘load’,function(){ … })
可使用相關 api
.responseText
:拿到資料.status
:拿到 Http status code 狀態碼
範例程式碼是發到 https://reqres.in/api/users ,回傳以下結果
換發 request 到 https://google.com ,結果:回傳錯誤訊息,以下為錯誤訊息:
ajax.html:1 Access to XMLHttpRequest at 'https://google.com/' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
意思指由於瀏覽器有安全性考量,有一個東西叫同源政策(Same-origin policy),他不准我們發 request 到 https://google.com/。
以上有錯誤的地方歡迎指正,感謝。