1.什么是同源策略?

如果两个 URL 的 protocol、port 和 host 都相同的话,则这两个 URL 是同源。同源策略对Web应用程序具有特殊意义,因为Web应用程序广泛依赖于HTTP cookie来维持用户会话,所以必须将不相关网站严格分隔,以防止丢失数据泄露。

值得注意的是同源策略仅适用于脚本,这意味着某网站可以通过相应的HTML标签访问不同来源网站上的图像、CSS和动态加载脚本等资源。而跨站请求伪造就是利用同源策略不适用于HTML标签的缺陷。

2.跨域资源共享 CORS

跨域资源共享(英语:Cross-origin resource sharing,缩写:CORS),用于让网页的受限资源能够被其他域名的页面访问的一种机制。

通过该机制,页面能够自由地使用不同源(英语:cross-origin)的图片、样式、脚本、iframes以及视频。一些跨域的请求(特别是Ajax)常常会被同源策略所禁止的。跨源资源共享定义了一种方式,为的是浏览器和服务器之间能互相确认是否足够安全以至于能使用跨源请求。比起纯粹的同源请求,这将更为自由和功能性的(functionality ),但比纯粹的跨源请求更为安全。

3.预检请求

需预检的请求要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

不会触发CORS预检的请求称为简单请求,满足以下所有条件的才会被视为简单请求

1)使用GET、POST、HEAD其中一种方法

2)只使用了如下的安全首部字段,不得人为设置其他首部字段

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type 只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

4.CORS相关字段

  • Access-Control-Allow-Origin:该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
  • Access-Control-Allow-Headers:表明服务器允许请求中携带的头信息字段。值为逗号分割的列表。
  • Access-Control-Allow-Credentials:该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
  • Access-Control-Allow-Methods:该字段必需,用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。
  • Access-Control-Max-Age:该字段可选,用来指定本次预检请求的有效期,单位为秒。在此期间,不用发出另一条预检请求。

5.Golang实现跨域

客户端

<!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)
}
}

6.参考资料

1.同源策略 - 维基百科

2.跨域资源共享 - 维基百科

3.跨域资源共享 CORS 详解 - 阮一峰的网络日志

最新文章

  1. Win7 64位下PowerDesigner连接64位Oracle11g数据库
  2. ios 根据文字数量计算UILabel高度(已修改)
  3. [转]使用 google gson 转换Timestamp或Date类型为JSON字符串.
  4. 关于个人博客和Github地址提交
  5. 第三十九课:requestAnimationFrame详解
  6. HTML页引用CSS
  7. 使用adb devices命令,老是报error:device offline的错误。
  8. Installutil.exe 注册exe
  9. 【模拟】Codeforces 671B Robin Hood
  10. POJ 1258 Agri-Net(Prim)
  11. C#小知识点记录,对象的深拷贝
  12. 恐怖的ifdown eth0;0
  13. 华硕笔记本电脑Win10改Win7设置U盘启动
  14. Codeforces 1154 - A/B/C/D/E/F/G - (Undone)
  15. 从数据类型 varchar 转换为 numeric 时出错.
  16. java类的设计原则
  17. C#实现物联网系统温度解析的函数(支持补码)
  18. Java字符串分割(转)
  19. PL/SQL之游标的使用
  20. # 20155214 2016-2017-2 《Java程序设计》第9周学习总结

热门文章

  1. Django-利用LogEntry生成操作历史
  2. AT5221 [ABC140C] Maximal Value 题解
  3. ftp:500 Illegal PORT command. 425
  4. 跨域:The &#39;Access-Control-Allow-Origin&#39; header contains multiple values &#39;*, *&#39;, but only one is allowed
  5. Tornado 异步浅解
  6. Android 崩溃错误
  7. 【LeetCode】948. Bag of Tokens 解题报告(Python)
  8. 【LeetCode】34. Find First and Last Position of Element in Sorted Array 解题报告(Python & C++)
  9. 【LeetCode】874. Walking Robot Simulation 解题报告(Python & C++)
  10. 【LeetCode】228. Summary Ranges 解题报告(Python)