📔
饥人谷前端体系课程笔记
黑马程序员笔记前端面试押题前端精进
  • 课程大纲
  • Git入门
    • 3. 软件安装详解
    • 4. Mac环境搭建
    • 5. 命令行入门
    • 6. 本地仓库
    • 7. Git远程仓库-GitHub
  • HTML全解
    • 8. HTML概览
    • 9. HTML标签
    • 10. HTML重难点
    • 11. HTML实践 & 手机调试
  • CSS全解
    • 12. CSS基础
    • 13. CSS布局(上)
    • 14. CSS布局(下)
    • 15. CSS定位
    • 16. CSS动画
  • HTTP全解
    • 17. URL 是什么
    • 18. 请求和响应 & Node.js Server
  • JS全解
    • 19. JavaScript概览
    • 20. 内存图与JS世界(精品课)
    • 21. Canvas 实践—画图板
    • 22. JS语法
    • 23. JS数据类型
    • 24. JS 对象
    • 25. JS 对象分类
    • 26. JS 数组
    • 27. JS 函数
    • 28. JS 实战,会动的代码
    • 29. JS运算符
    • 30. JS总结
  • JS编程接口
    • 31. DOM编程
    • 32. 手写DOM库
    • 33. JQuery中的设计模式(上)
    • 34. JQuery中的设计模式(下)
    • 35. DOM事件与事件委托
  • 项目 前端导航站点
    • 前端导航项目笔记
  • 前后分离
    • 40. AJAX的原理
    • 41. 异步与Promise
    • 42. 跨域、CORS、JSONP
    • 43. 静态服务器
    • 44. AJAX实战:Cookie、Session
  • JS进阶MVC
    • 48. MVC(上)
    • 49. MVC(中)
    • 50. MVC(下)
  • 项目构建
    • 51. Webpack(上)
    • 52. Webpack(下)
  • 算法与数据结构
    • 62. 伪代码与流程图
  • React全解
    • 75. React起手式
    • 76. React类组件和函数组件
    • 77. Class组件详解
    • 78. 函数组件
    • 79. Hooks原理解析
    • 80. Hooks各个击破
    • 81. 精通Redux
  • Node.js
    • 84. Node.js技术架构
    • 85. 文件模块
    • 86. 单元测试之文件模块
    • 87. 调试 Node.js 程序
    • 88. 静态服务器
    • 89. 命令行翻译工具
    • 90. 操作数据库
    • 91. 数据库基础知识
    • 92. Stream 流
    • 93. child_process
    • 94. 总结
  • TypeScript
    • 112. 基础
    • 113. 泛型
  • Next.js全解
    • Next.js 上
    • Next.js 下
  • ES6精讲
    • Promise,async/await
  • 大屏可视化笔记
    • 大屏可视化项目
  • SCSS全解
    • SCSS全解
  • 拓展
    • 一次性弄懂性能优化
    • Web性能优化
由 GitBook 提供支持
在本页
  • 跨域
  • 跨域关键知识
  • 同源策略-什么是同源?
  • 同源定义
  • 同源策略定义
  • 如果没有同源策略
  • 问题的根源
  • 同源策略
  • 修改hosts
  • 跨域 AJAX
  • 其他新手疑问
  • 面试问题:请问怎么跨域?
  • 解法一:CORS(Cross-origin Resource Sharing跨域资源共享)
  • JSONP
  • JSONP 是什么
  • 第 1 题
  • 第 2 题

这有帮助吗?

  1. 前后分离

42. 跨域、CORS、JSONP

跨域-从入门到工作:前后端分离

跨域

⚠️面试必必必问,菜逼必定不会答

新手这题肯定答不上来,老手多多少少都能答上来,是一道用来区分有经验和没经验的面试题。

这块儿的知识要写过JS和AJAX的程序员才能答上来,有工作几年都没有遇到过这些的问题的程序员。

跨域关键知识

  • 同源策略(Same-origin policy)

    • 浏览器故意设计的一个功能限制

  • CORS(Cross-origin Resource Sharing跨域资源共享)

    • 突破浏览器限制的一个方法

  • JSONP

    • IE 时代的妥协

同源策略-什么是同源?

同源定义

  • 源

    • window.origin 或 location.origin 可以得到当前源(在页面打开开发者工具,console里面输入)

    • 源 = 协议 + 域名 + 端口号(端口号默认是80)

  • 如果两个 url 的

    • 协议

    • 域名

    • 端口号

    • 完全一致,那么这两个 url 就是同源的

  • 举例

    • 完全一致才算同源

同源策略定义

  • 浏览器规定

    • 如果 JS 运行在 源 A 里,那么就只能获取源 A 的数据

    • 不能获取源 B 的数据,即 不允许跨域

  • 举例(省略 http 协议)

    • 假设 frank.com/index.html 引用了 cdn.com/1.js

    • 那么就说「 1\.js 运行在 源 frank\.com 里」

    • 注意这跟 cdn.com 没有关系,虽然 1.js 从它那 下载

    • 所以 1.js 就只能获取 frank.com 的数据

    • 不能获取 1.frank.com 或者 qq.com 的数据

  • 这是浏览器的功能!

    • 浏览器故意要这样设计的

浏览器这样做的目的是啥?

  • 为了保护用户隐私!

怎么保护的?

如果没有同源策略

  • 以 QQ 空间为例

    • 假设,当前用户已经登录(用 Cookie,后面会讲)

    • 假设,AJAX 请求 /friends.json 可获取用户好友列表

    • 到目前为止都很正常

  • 黑客来了

    • 实际上这是一个钓鱼网站

    • 你点开这个网页,这个网页也请求你的好友列表

    • 请问,你的好友列表是不是就把黑客偷偷偷走了?

    • 好像是哦……

问题的根源

  • 无法区分发送者

    • QQ 空间页面里的 JS 和黑客网页里的 JS

    • 发的请求几乎没有区别(referrer 有区别)

    • 如果后台开发者没有检查 referer,那么就完全没区别

    • 所以,没有同源策略,任何页面都能偷 QQ 空间的数据

    • 甚至支付宝余额!

    referrer:

    XHR: 即xml http request的缩写

  • 那检查 referer 不就好了?

    • 安全原则:安全链条的强度取决于最弱一环

    • 万一这个网站的后端开发工程师是个傻 X 呢

    • 所以浏览器应该主动预防这种偷数据的行为

    • 总之,浏览器为了用户隐私,设置了严格的同源策略

同源策略

不同源的页面之间,不准互相访问数据

你说了这么多,可有证据?

我们需要做两个网站来演示一下

  • 步骤

  • 创建目录

  • qq-com

    • /index.html 是首页

    • /qq.js 是 JS 脚本文件

    • /friends.json 是模拟的好友数据

  • frank-com

    • /index.html 是首页

    • /frank.js 是 JS 脚本文件

修改hosts

目的:上面做测试的两个ip地址是一样的,为了证明同源策略,使用host来修改成两个不一样的ip地址。

  • 设置本地域名映射

    • 让 qq.com 映射到 127.0.0.1

    • 让 frank.com 映射到 127.0.0.1

    • 修改完之后可以去terminal ping一下

      ping qq.com
      //等于不通过DNS,劫持了域名
  • 如何设置 hosts

    • 需要用管理员权限操作host

    • 老师,我没用管理员权限怎么也可以? ——哦

    • 百度搜索 Win7 设置 hosts

    • 百度搜索 Win10 设置 hosts

    • 百度搜索 mac 设置 hosts

    • 百度搜索 Ubuntu 设置 hosts

    • 每个系统方法不同,我只演示我的系统

跨域 AJAX

  • 正常使用 AJAX

    • 在 qq.com:8888 里运行的 JS 可以访问 /friends.json

  • 黑客偷数据

    • 在 frank.com:9999 里运行的 JS 不能访问!

    • 浏览器需要 CORS

  • 提问

    • 黑客的请求发成功了没有?

    • 答:成功了,因为 qq.com 后台有 log

    • 黑客拿到响应了没有?

    • 答:没有,因为浏览器不给数据给它

就没有浏览器不限制跨域么

如果不限制,就是浏览器 bug 了,快向浏览器反馈

其他新手疑问

  • 为什么 a.qq.com 访问 qq.com也算跨域?

  • 答:因为历史上,出现过不同公司共用域名,a.qq.com 和 qq.com 不一定是同一个网站,浏览器谨慎起见,认为这是不同的源

  • 为什么不同端口也算跨域?

  • 答:原因同上,一个端口一个公司。记住安全链条的强度取决于最弱一环,任何安全相关的问题都要谨慎对待

  • 为什么两个网站的IP 是一样的,也算跨域?

  • 答:原因同上,IP 可以共用。

  • 为什么可以跨域使用CSS 、JS 和图片等?

  • 答:同源策略限制的是数据访问,我们引用 CSS、JS 和图片的时候,其实并不知道其内容,我们只是在引用。不信我问你,你能知道 CSS 的第一个字符是什么吗?

面试问题:请问怎么跨域?

面试官会问你,工作中也会遇到

解法一:CORS(Cross-origin Resource Sharing跨域资源共享)

  • 问题根源

    • 浏览器默认不同源之间不能互相访问数据

    • 但是 qq.com 和 frank.com 其实都是方方的网站

    • 方方就是想要两个网站互相访问,浏览器为什么阻止

  • 好吧,用 CORS

    • 浏览器说,如果要共享数据,需要提前声明!

    • 哦,那怎么声明呢?

    • 浏览器说,qq.com 在响应头里写 frank.com 可以访问

    • 哦,具体语法呢?

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

CORS 就这么简单?!

是的,就一句话的事情。想想看,是否完美解决了问题? 是的

注意:CORS 分为简单请求和复杂请求,具体看文档

IE 说:你猜我支持不支持

哪还用猜?艹 IE 6 7 8 9

那么如果要兼容 IE,怎么办(用JSONP)

JSONP

  • 定义

    • JSONP 和 JSON 半毛钱关系都没有

    • 由于前端水平低下,错误地将其称为 JSONP

    • 具体定义看后面代码

  • 我们现在面临地问题是什么

    • 程序员常常面临奇葩需求

    • 没有 CORS,怎么跨域

    • 记不记得我们可以随意引用 JS

    • 虽然我们不能访问 qq.com:8888/friends.json

    • 但是我们能引用 qq.com:8888/friends.js 啊!

    • 这有什么用?JS 又不是数据

    • 我们让 JS 包含数据不就好了……

    • 试试看吧!明天就要上线啦!

  • 步骤

  • frank.com 访问 qq.com

    • qq.com 将数据写到 /friends.js

    • frank.com 用 script 标签引用 /friends.js

    • /friends.js 执行,执行什么呢?

    • frank.com 事先定义好 window.xxx 函数

    • /friends.js 执行 window.xxx({frinds:[...]})

    • 然后 frank.com 就通过 window.xxx 获取到数据了

    • window.xxx 就是一个回调啊!

    • 这 TM 都能想到,人才啊!

    • 这是很多前端工程师一起想出来的

  • 优化

  • xxx 能不写死吗?

    • window.xxx 能不能改其他名字?

    • 其实名字不重要,只要 frank.com 定义的函数名和 qq.com/friends.js 执行的函数名是同一个即可!

    • 那就把名字传给 /friends.js !

    • 看我改代码

  • 再优化

  • 封装!

    • 初级程序员学 API,中级程序员学封装。

    • 封装成 jsonp('url').then(f1, f2)

      function  jsonp(url){
      return  new  Promise((resolve, reject) => {
      	const random = "frankJSONPCallbackName"   +  Math.random();
      	window[random]  =  data => {
      		resolve(data);
      	};
      	const  script  =  document.createElement("script"); 
        script.src =  `${url}?callback=${random}` ; 
        script.onload = ()=> {
      		script.remove();
      	};
      	script.onerror = ()=>{
          reject();
        }
      	document.body.appendChild(script); 
      });
      }
      
      jsonp('http://qq.com:8888/friend.js')
      .then((data) =>{
        console.log(data);
      })

JSONP 是什么

完美回答面试官JSONP是什么?

  1. JSONP是什么?

    当浏览器不支持CORS,必须使用另一种方式来实现跨域,于是就请求一个js文件,这个js文件会执行一个回调,回调里面就会有我们的数据。

    另一种解释:我们当前的网站用一个script,去请求另一个网站的js,js里面会包含一些数据,js会在我们当前的网站上调用一个全局函数来运行。

    面试官followup:这个回调的名字叫什么?

    这个回调的名字可以随机生成,以callback传给后台,后台会再次把值返回给我们,并且执行。

  2. JSONP的优缺点,回答出来可以加分

    优点:兼容IE,可以跨域

    缺点:由于是script标签,所以读不到像AJAX那样的状态码和header,以及只能发get请求,不能使用post。

以上就是跨域的所有内容

足够大家搞定面试和工作

作业:

第 1 题

请模仿视频,创建 qq.com:8888 和 frank.com:9999,然后在 frank.com 用 AJAX 请求 qq.com 的 /friends.json

要求使用 CORS。成功请求到之后请对响应头截图,截图里应该清晰的看到 Access-Control-Allow-Origin 字样。

第 2 题

请模仿视频,创建 qq.com:8888 和 frank.com:9999,然后在 frank.com 用 JSONP 请求 qq.com 的 /friends.js

要求使用 JSONP。成功请求到之后请对响应体截图,截图里应该清晰的看到 JSONP 的内容。

上一页41. 异步与Promise下一页43. 静态服务器

最后更新于2年前

这有帮助吗?

、 不同源(域名不一样)

、 不同源(一个有www,一个没有,这也是不同源)

源为

假设你的女神分享 给你

截屏2023-04-18 下午5.00.42

qq-com 里面有一个 ,用来模拟 QQ 空间

frank-com 里面有一个 ,用来模拟坏人网站

端口监听为 8888,访问

端口监听为 9999,访问

就可以访问 了

就可以访问 了

截屏是在window操作系统下

Access-Control-Allow-Origin:

浏览器说:都得文档里,去看 嘛

https://qq.com
https://www.baidu.com
https://baidu.com
https://www.baidu.com
https://
user.qzone.qq.com
https://qzone-qq.com
https://user.qzone.qq.com/friends.json
server.js
server.js
http://127.0.0.1:8888
http://127.0.0.1:8889
http://qq.com:8888/index.html
http://frank.com:9999/index.html
http://
foo.example
MDN
文档