如果两个 URL 的 protocol、port 和 host 都相同的话,则这两个 URL 是同源。同源策略对Web应用程序具有特殊意义,因为Web应用程序广泛依赖于HTTP cookie来维持用户会话,所以必须将不相关网站严格分隔,以防止丢失数据泄露。
值得注意的是同源策略仅适用于脚本,这意味着某网站可以通过相应的HTML标签访问不同来源网站上的图像、CSS和动态加载脚本等资源。而跨站请求伪造就是利用同源策略不适用于HTML标签的缺陷。
跨域资源共享(英语:Cross-origin resource sharing,缩写:CORS),用于让网页的受限资源能够被其他域名的页面访问的一种机制。
通过该机制,页面能够自由地使用不同源(英语:cross-origin)的图片、样式、脚本、iframes以及视频。一些跨域的请求(特别是Ajax)常常会被同源策略所禁止的。跨源资源共享定义了一种方式,为的是浏览器和服务器之间能互相确认是否足够安全以至于能使用跨源请求。比起纯粹的同源请求,这将更为自由和功能性的(functionality ),但比纯粹的跨源请求更为安全。
需预检的请求要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。
不会触发CORS预检的请求称为简单请求,满足以下所有条件的才会被视为简单请求
1)使用GET、POST、HEAD其中一种方法
2)只使用了如下的安全首部字段,不得人为设置其他首部字段
客户端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XMLHttpRequest CORS</title>
</head>
<body>
<h2>XMLHttpRequest CORS</h2>
<button id="send">发送POST(application/x-www-form-urlencoded)</button>
<button id="sendJSON">发送POST(application/json)</button>
<script type="application/javascript">
document.getElementById(‘send‘).onclick = function (evt) {
let xhr = new XMLHttpRequest();
xhr.open("POST", "http://127.0.0.1:8080/index", true)
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
xhr.setRequestHeader("x-Custome-Header", "true")
let params = new URLSearchParams()
params.append("name", "dazuo")
params.append("age", "24")
xhr.send(params)
}
document.getElementById(‘sendJSON‘).onclick = function (evt) {
let xhr = new XMLHttpRequest();
xhr.open("POST", "http://127.0.0.1:8080/index", true)
xhr.setRequestHeader("Content-Type", "application/json")
xhr.setRequestHeader("x-Custome-Header", "true")
let postData = JSON.stringify({
name: "dazuo",
age: 24
})
xhr.send(postData)
}
</script>
</body>
</html>
服务端
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func HTTPCORS() {
http.HandleFunc("/index", func(w http.ResponseWriter, r *http.Request) {
header := w.Header()
header.Set("Access-Control-Allow-Origin", "*")
header.Set("Access-Control-Allow-Headers", "x-Custome-Header,Content-Type")
header.Set("Access-Control-Allow-Credentials", "false")
header.Set("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT,OPTIONS")
header.Set("Access-Control-Max-Age", "5")
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusNoContent)
}
reqBody, _ := ioutil.ReadAll(r.Body)
fmt.Printf("RequestURI: %s, Methods: %s, ReqBody: %s\n", r.RequestURI, r.Method, reqBody)
_, _ = w.Write([]byte("welcome !"))
})
err := http.ListenAndServe("127.0.0.1:8080", nil)
if err != nil {
log.Panic(err)
}
}
原文:https://www.cnblogs.com/maxzuo/p/13550930.html