# 4-6 、 同源政策與跨來源共用 ###### tags: `FE102` `HTML+CSS` `2020九月第一周` `進度筆記` `Lidemy心得` 09/09 ## Same Origin Policy - 同源政策 ==送 `` request.open('GET', 'https://google.com', true)`` 時,因為有 CORS policy , 所以不能送出。== - 如相同 Domain 、 相同網域就是同源(除非共用同個 Domain)。 - 但 http 和 https , 不同 port 、 整個網址都不同就是是不同源。 - 瀏覽器預設,不同源就會阻擋進入。 ## 跨來源資源共用 (Cross-Origin Resource Sharning, CORS) - 是個為了解決不同源的進入方法,如有時要去其他 Server 串接資料。 - 因此規範說,如果要跨來源就要在 Response 加個 Header: ``` Access-Control-Allow-Origin: * * 表示所有的 Origin 都能存取。 ``` - 如果 Server 沒有加上上述的 Response Header 是無法被存取拿資料的。 - 那些來源的人可以存取這個 API 或是網站 、 Server 資源。 來源即是發 request 時,瀏覽器會在 request 上加上 Origin , 而 Server 那就會根據來源來判斷是否給權限存取; 這個 Response Header 是瀏覽器加上的限制,除非同源、或是 Server 端加上這個 Response Header 才能存取。 --- 參考資料: [輕鬆理解Ajax 與跨來源請求 - TechBridge 技術共筆部落格](https://blog.techbridge.cc/2017/05/20/api-ajax-cors-and-jsonp/) [同源政策(Same-origin policy) - Web 安全| MDN](https://developer.mozilla.org/zh-TW/docs/Web/Security/Same-origin_policy) [跨來源資源共用(CORS) - HTTP | MDN](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/CORS) [同源政策與跨來源資源共用(CORS) | PJCHENder 未整理筆記](https://pjchender.github.io/2018/08/20/%E5%90%8C%E6%BA%90%E6%94%BF%E7%AD%96%E8%88%87%E8%B7%A8%E4%BE%86%E6%BA%90%E8%B3%87%E6%BA%90%E5%85%B1%E7%94%A8%EF%BC%88cors%EF%BC%89/) [打造Messenger Extension - Day 3 - CORS, Same-origin policy ...](https://ithelp.ithome.com.tw/articles/10190885) [深入認識跨域請求| iThome](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwjWnIz8pILsAhUKGqYKHWi9DVwQFjAEegQIAhAB&url=https%3A%2F%2Fwww.ithome.com.tw%2Fvoice%2F129558&usg=AOvVaw2WDaeK1KVE8NgFPG8LHjtz) [原來CORS 沒有我想像中的簡單 - TechBridge 技術共筆部落格](https://blog.techbridge.cc/2018/08/18/cors-issue/) --- # 4-7 、 瀏覽器管很大 ? ###### tags: `FE102` `HTML+CSS` `2020九月第一周` `進度筆記` `Lidemy心得` 09/09 - ==最主要是為了安全性,所以瀏覽器會有很多跟安全性有關的限制。== - 例如無法隨意讀取任意電腦的檔案,這樣才符合安全性的考量。 - 同源政策和 CORS 只跟瀏覽器有關。 因此如果用 Node.js 寫個 code , 無論 Server 是否同源有無 Header 都能 Catch : ``` const request = require('request') request.patch( { url:'https://reqres.in/api/users/2', form: { name:'hello' } }, function (error, response, body) { console.log(response.statusCode) console.log(body) } ); ``` 脫離了瀏覽器就不會有同源限制和 CORS 。 --- 參考資料: [不只是瀏覽器!JavaScript 征服世界的第一步- Node.js (Day 8 ...](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwij2I_RrILsAhVHHaYKHVPoD7MQFjADegQIAxAB&url=https%3A%2F%2Fithelp.ithome.com.tw%2Farticles%2F10191345&usg=AOvVaw3UkIZ9Hu_WOZbtXr2Vk06x) --- # 4-8 、 第三種交換方式 - JSONP ###### tags: `FE102` `HTML+CSS` `2020九月第一周` `進度筆記` `Lidemy心得` 09/09 - 現在比較少用。 ## JSONP - JSON with Padding 。 - 但是 AJAX 一定受同源政策管理。 - 有些標籤不受同源政策影響,例如 ``<img src="" />`` , 跨來源圖片一樣可以載入。 - 以及 src 可以引進其他 Domain 的 JS 進來 , `<script src="https://"></script>` 。 - 也可以用 script 來拿東西 , 可以在 Client 端宣告一個 function : ``` <script> //定義好 setData 函式後,等網址載入後就會拿到資料。 function setData(users) { console.log(users) } </script> <script src="http://test.com/user.js"></script> <!--用網址的頁面,內有 JS 執行一個 function 把 Data 傳出去--> <script> const request = new XMLHttpRequest() const element = document.createElement('script') element.src = 'http://test.com/user.js?id=1' // 這邊可以代參數 , server 端可以根據 ↑ 輸出想要的內容。 ``` ==而Server 端回傳的資料會是 JS Obj 的資料,可能以上面來說會像是這樣:== ``` // user.js setData( { id:1, name: 'hello' } ) ``` --- 參考資料: [JSONP - JSON 教學Tutorial - Fooish 程式技術](https://www.fooish.com/json/jsonp.html) [使用JSONP 跨站請求 - OpenHome.cc](https://openhome.cc/Gossip/JavaScript/JSONP.html) [Cross Domain Ajax 跨網域抓取資料(JSONP) - iT 邦幫忙 - iThome](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwio0cWwq4TsAhXtyYsBHc35Dt4QFjAOegQICxAB&url=https%3A%2F%2Fithelp.ithome.com.tw%2Farticles%2F10094915&usg=AOvVaw3O8-j8ZGuk1_ZkGnrHoOaD) # 4-9 、 一方通行 ###### tags: `FE102` `HTML+CSS` `2020九月第一周` `進度筆記` `Lidemy心得` 09/09 ## 單向傳輸資料 - 有時只想傳資料回去而不想拿到 Response 。 - 可能會應用在廣告商的追蹤或,發 E-mail 的網站,發出去後可以看到有多少使用者打開這封信。 - 會在 E-mail 內放張圖片,可能 1 * 1 大小: ``` <img width="1" height="1" src="某個位址" /> ``` 開信的時候會 Loading 這張圖片,因此會發個 Request 到"某個位址"去,因此就能得知有人打開這封信。 --- # 4-10 、 Catch And Shoot ###### tags: `FE102` `HTML+CSS` `2020九月第一周` `進度筆記` `Lidemy心得` 09/09 ## 抓取資料並顯示 實際用 AJAX 拿資料,有資料就可以進行切版: 1. 拿到 responseText 資料後把它變成: ``` // 這種形式: <div class="profile"> <div class="profile__name">George Bluth</div> <img class="profile__img" src="https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg" /> </div> ``` ==先把版面刻好,樣式套一套。== 2. 然後再 append 到 `<div class='app'>` 底下。 ``` <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>瀏覽器上執行 JS</title> <style> body {font-size: 38px;} .profile { border: 1px solid #333; margin-top: 20px; display: inline-flex; align-items: center; } .profile__name { margin: 0px 10px; } </style> </head> <body> <div class='app'></div> <script> const request = new XMLHttpRequest() const container = document.querySelector('.app') request.addEventListener('load', function() { if (request.status >= 200 && request.status < 400) { const response = request.responseText const json = JSON.parse(response) const users = json.data for(let i = 0; i< users.length; i++) { const div = document.createElement('div') div.classList.add('profile') div.innerHTML = ` <div class="profile__name">${users[i].first_name} ${users[i].last_name} </div> <img class="profile__img" src="${users[i].avatar}" /> ` container.appendChild(div) } } else { console.log('request.status, request.responseText') } }) request.onerror = function() { console.log('error') } request.open('GET', 'https://reqres.in/api/users', true) request.send() </script> </body> </html> ``` - 然後用 innerHTML 的方式寫,用 JS 把資料動態換成 Server 拿下來的寫死的資料。 - 這樣就會完成與 Server 連動的網頁。 就可以讓資料顯示在版面。 ![](https://i.imgur.com/H8rlfPZ.png) 把網路上的資料拿下來,用 AJAX 的方式。 # 4-11 、 內容產生在 Client 還是 Server ? ###### tags: `FE102` `HTML+CSS` `2020九月第一周` `進度筆記` `Lidemy心得` 09/10 - 4-10 用 JS 把資料動態換成 Server 拿下來的寫死的資料。 - 右鍵檢視原始碼時,在 Body 內看不到任何東西。 ![](https://i.imgur.com/csvBOs6.png) ==檢視原始碼是檢視檔案的內容。== - 因為是執行 JS 才把資料動態顯示,這方式為: ==`Client Side Rendering`== - 壞處在於搜尋引擎會覺得這頁面沒有內容,很多搜尋引擎不會幫忙執行 JS 。 --- 1. 以 JS 面相來說,如何改變 UI 。 2. 如何讓 JS 監聽和更改事件做出反應。 3. 跟 Server 交換資料的方法。 ---