同源

window.origin或location.origin得到源
源 = 协议 + 域名 + 端口号

如果两个url的源完全一致,则是同源
https://qq.com、https://www.baidu.com不同源
https://baidu.com、https://www.baidu.com不同源

同源策略

浏览器规定
运行在源A里的JS不能获取源B里的数据,即不允许跨域
作用:保护用户隐私

跨域测试

image.png
引用文件,能访问,也不能知道内容是什么

方案一:CORS

将发起请求的源写入Access-Control-Allow-Origin

  1. response.setHeader("Access-Control-Allow-Origin","http://frank.com:9999")

方案二:JSONP

IE6 7 8 9不支持CORS

新建一个friends.js,添加占位符
image.png
添加server路由
image.png
请求到数据
image.png
但这不是合法的JS
修改为
image.png
再次获取
image.png
修改其他源的获取方式
image.png
获取到数据
image.png

改用回调函数
image.pngimage.png
但是,这样每个人都能请求到friends.js,所以用referer定向分享
image.png
优化:使用随机函数名
image.png
image.png
image.png

防止页面臃肿
image.png

封装JSONP

  1. function jsonp(url){
  2. return new Promise((resolve, reject) =>{
  3. const random = "frankJSONCallbackName" + Math.random()
  4. window[random] = (data)=>{
  5. resolve(data)
  6. }
  7. const script = document.createElement("script")
  8. script.src = `${url}?callback=${random}` // 传递查询参数
  9. script.onload = ()=>{
  10. script.remove() // 拿到数据后就删掉script,防止页面臃肿
  11. }
  12. script.onerror = ()=>{
  13. reject()
  14. }
  15. document.body.appendChild(script)
  16. })
  17. }
  18. jsonp('http://qq.com:8888/friends.js')
  19. .then((data)=>{
  20. console.log(data)
  21. })

JSONP是什么?

因为某些原因,浏览器不支持CORS跨域,所以采用JSONP
于是我们请求一个JS文件,JS里执行回调函数,回调函数里有我们要的数据
回调函数的名称可以随机生成
请求JS文件时,后台会把我们要的数据传给回调函数,并执行

JSONP的优点是兼容IE,可以跨域
缺点是它是用script标签发请求,读不到像ajax那样精确的状态(ajax可以获取readyState和status),拿不到状态码和header,且只能发GET请求,不支持POST