# 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 連動的網頁。
就可以讓資料顯示在版面。

把網路上的資料拿下來,用 AJAX 的方式。
# 4-11 、 內容產生在 Client 還是 Server ?
###### tags: `FE102` `HTML+CSS` `2020九月第一周` `進度筆記` `Lidemy心得` 09/10
- 4-10 用 JS 把資料動態換成 Server 拿下來的寫死的資料。
- 右鍵檢視原始碼時,在 Body 內看不到任何東西。

==檢視原始碼是檢視檔案的內容。==
- 因為是執行 JS 才把資料動態顯示,這方式為: ==`Client Side Rendering`==
- 壞處在於搜尋引擎會覺得這頁面沒有內容,很多搜尋引擎不會幫忙執行 JS 。
---
1. 以 JS 面相來說,如何改變 UI 。
2. 如何讓 JS 監聽和更改事件做出反應。
3. 跟 Server 交換資料的方法。
---