🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
> 题目:如何实现跨域? 浏览器中有**同源策略**,即一个域下的页面中,无法通过 Ajax 获取到其他域的接口。例如有一个接口`http://m.juejin.com/course/ajaxcourserecom?cid=459`,你自己的一个页面`http://www.yourname.com/page1.html`中的 Ajax 无法获取这个接口。这正是命中了“同源策略”。如果浏览器哪些地方忽略了同源策略,那就是浏览器的安全漏洞,需要紧急修复。 url 哪些地方不同算作跨域? * 协议 * 域名 * 端口 但是 HTML 中几个标签能逃避过同源策略——`<script src="xxx">`、`<img src="xxxx"/>`、`<link href="xxxx">`,这三个标签的`src/href`可以加载其他域的资源,不受同源策略限制。 因此,这使得这三个标签可以做一些特殊的事情。 * `<img>`可以做打点统计,因为统计方并不一定是同域的,在讲解 JS 基础知识异步的时候有过代码示例。除了能跨域之外,`<img>`几乎没有浏览器兼容问题,它是一个非常古老的标签。 * `<script>`和`<link>`可以使用 CDN,CDN 基本都是其他域的链接。 * 另外`<script>`还可以实现 JSONP,能获取其他域接口的信息,接下来马上讲解。 但是请注意,所有的跨域请求方式,最终都需要信息提供方来做出相应的支持和改动,也就是要经过信息提供方的同意才行,否则接收方是无法得到它们的信息的,浏览器是不允许的。 ### 解决跨域 - JSONP 首先,有一个概念你要明白,例如访问`http://coding.m.juejin.com/classindex.html`的时候,服务器端就一定有一个`classindex.html`文件吗?—— 不一定,服务器可以拿到这个请求,动态生成一个文件,然后返回。 同理,`<script src="http://coding.m.juejin.com/api.js">`也不一定加载一个服务器端的静态文件,服务器也可以动态生成文件并返回。OK,接下来正式开始。 例如我们的网站和掘金网,肯定不是一个域。我们需要掘金网提供一个接口,供我们来获取。首先,我们在自己的页面这样定义 ~~~ <script> window.callback = function (data) { // 这是我们跨域得到信息 console.log(data) } </script> ~~~ 然后掘金网给我提供了一个`http://coding.m.juejin.com/api.js`,内容如下(之前说过,服务器可动态生成内容) ~~~ callback({x:100, y:200}) ~~~ 最后我们在页面中加入`<script src="http://coding.m.juejin.com/api.js"></script>`,那么这个js加载之后,就会执行内容,我们就得到内容了。 ### 解决跨域 - 服务器端设置 http header 这是需要在服务器端设置的,作为前端工程师我们不用详细掌握,但是要知道有这么个解决方案。而且,现在推崇的跨域解决方案是这一种,比 JSONP 简单许多。 ~~~ response.setHeader("Access-Control-Allow-Origin", "http://m.juejin.com/"); // 第二个参数填写允许跨域的域名称,不建议直接写 "*" response.setHeader("Access-Control-Allow-Headers", "X-Requested-With"); response.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); // 接收跨域的cookie response.setHeader("Access-Control-Allow-Credentials", "true"); ~~~