首先了解一些什么是跨域,什么情况下会产生跨域:
当主域名、子域名、端口号、以及协议任意一个不同时,就会产生跨域,当然,如果Ajax请求时,请求方式不是XHR的话,浏览器是不会限制这种跨域的,在Ajax请求跨域时再详细介绍。
域名:
<span style="color:#333333"><span style="color:#000000"><code>主域名不同 http://www<span style="color:#009900">.baidu</span><span style="color:#009900">.com</span>/index<span style="color:#009900">.html</span> –>http://www<span style="color:#009900">.sina</span><span style="color:#009900">.com</span>/test<span style="color:#009900">.js</span>
子域名不同 http://www<span style="color:#006666">.666</span><span style="color:#009900">.baidu</span><span style="color:#009900">.com</span>/index<span style="color:#009900">.html</span> –>http://www<span style="color:#006666">.555</span><span style="color:#009900">.baidu</span><span style="color:#009900">.com</span>/test<span style="color:#009900">.js</span>
域名和域名ip http://www<span style="color:#009900">.baidu</span><span style="color:#009900">.com</span>/index<span style="color:#009900">.html</span> –>http://<span style="color:#006666">180.149</span><span style="color:#006666">.132</span><span style="color:#006666">.47</span>/test<span style="color:#009900">.js</span>
端口 http://www<span style="color:#009900">.baidu</span><span style="color:#009900">.com</span>:<span style="color:#006666">8080</span>/index<span style="color:#009900">.html</span>–> http://www<span style="color:#009900">.baidu</span><span style="color:#009900">.com</span>:<span style="color:#006666">8081</span>/test<span style="color:#009900">.js</span>
协议 http://www<span style="color:#009900">.baidu</span><span style="color:#009900">.com</span>:<span style="color:#006666">8080</span>/index<span style="color:#009900">.html</span>–> https://www<span style="color:#009900">.baidu</span><span style="color:#009900">.com</span>:<span style="color:#006666">8080</span>/test<span style="color:#009900">.js</span> </code></span></span>
- 1
- 2
- 3
- 4
- 5
window跨域
window跨域指不同域名的页面之进行间数据传输或通信。
document.domian+ifram
注意,使用这种方法一定要主域名相同才可以使用
<span style="color:#333333"><span style="color:#000000"><code>//www.test.come/index.html
<span style="color:#006666"><<span style="color:#4f4f4f">iframe</span> <span style="color:#4f4f4f">src</span>=<span style="color:#009900">"http://www.new.test.com/index.html"</span> <span style="color:#4f4f4f">frameborder</span>=<span style="color:#009900">"0"</span> <span style="color:#4f4f4f">id</span>=<span style="color:#009900">'iframe'</span> <span style="color:#4f4f4f">onload</span>=<span style="color:#009900">"test()"</span>></span><span style="color:#006666"></<span style="color:#4f4f4f">iframe</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">script</span> <span style="color:#4f4f4f">type</span>=<span style="color:#009900">"text/javascript"</span>></span>
document.domain = <span style="color:#009900">'test.com'</span>;
<span style="color:#000088">function</span> <span style="color:#009900">test</span><span style="color:#4f4f4f">()</span> {
<span style="color:#000088">var</span> fir = document.getElementById(<span style="color:#009900">'iframe'</span>);
console.log(fir.firstElementChild);
}
<span style="color:#006666"></<span style="color:#4f4f4f">script</span>></span>
//www.new.test.com/index.html
<span style="color:#006666"><<span style="color:#4f4f4f">ul</span> <span style="color:#4f4f4f">id</span>=<span style="color:#009900">"ul_test"</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">li</span>></span>哈哈哈<span style="color:#006666"></<span style="color:#4f4f4f">li</span>></span>
<span style="color:#006666"></<span style="color:#4f4f4f">ul</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">script</span> <span style="color:#4f4f4f">type</span>=<span style="color:#009900">"text/javascript"</span>></span>
document.domain = <span style="color:#009900">'test.com'</span>;
<span style="color:#006666"></<span style="color:#4f4f4f">script</span>></span></code></span></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
最终结果如下:
window.name
window.name对跨域完全毫无限制,只是window.name中的内容最大就是2M。可以把需要传递的信息放在window.name中。
<span style="color:#333333"><span style="color:#000000"><code><span style="color:#006666"><<span style="color:#4f4f4f">iframe</span> <span style="color:#4f4f4f">src</span>=<span style="color:#009900">"http://www.new.test.com/index.html"</span> <span style="color:#4f4f4f">frameborder</span>=<span style="color:#009900">"0"</span> <span style="color:#4f4f4f">id</span>=<span style="color:#009900">'iframe'</span> <span style="color:#4f4f4f">onload</span>=<span style="color:#009900">"test()"</span>></span><span style="color:#006666"></<span style="color:#4f4f4f">iframe</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">script</span> <span style="color:#4f4f4f">type</span>=<span style="color:#009900">"text/javascript"</span>></span>
<span style="color:#000088">function</span> <span style="color:#009900">test</span><span style="color:#4f4f4f">()</span> {
<span style="color:#000088">var</span> fir = document.getElementById(<span style="color:#009900">'iframe'</span>);
console.log(fir.contentWindow.name);
}
<span style="color:#006666"></<span style="color:#4f4f4f">script</span>></span>
//www.new.test.com/index.html
<span style="color:#006666"><<span style="color:#4f4f4f">script</span> <span style="color:#4f4f4f">type</span>=<span style="color:#009900">"text/javascript"</span>></span>
window.name= <span style="color:#009900">'这里是你需要的信息'</span>;
<span style="color:#006666"></<span style="color:#4f4f4f">script</span>></span></code></span></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
Ajax请求跨域
现在大多数项目都前后端分离了,这样的话,就避免不了处理跨域的问题。
jsonp处理请求跨域
可以使用jQuery的ajax,它已经把jsonp封装好了,具体代码如下:
<span style="color:#333333"><span style="color:#000000"><code><span style="color:#006666"><<span style="color:#4f4f4f">script</span>></span>
$(<span style="color:#000088">function</span><span style="color:#4f4f4f">()</span>{
$.ajax({
url:<span style="color:#009900">'XXX'</span>,
async:<span style="color:#006666">true</span>,
type:<span style="color:#009900">'get'</span>,
dataType:<span style="color:#009900">'jsonp'</span>,
jsonp:<span style="color:#009900">'callback'</span>,<span style="color:#880000">//callback是与后台约定的返回参数,如果不一致的话也会报错</span>
data:<span style="color:#009900">''</span>,
timeout:<span style="color:#006666">3000</span>,
contentType:<span style="color:#009900">'application/json;utf-8'</span>,
success:<span style="color:#000088">function</span><span style="color:#4f4f4f">(data)</span>{
console.log(data);
}
});
})
<span style="color:#006666"></<span style="color:#4f4f4f">script</span>></span></code></span></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
webpack设置代理
<span style="color:#333333"><span style="color:#000000"><code><span style="color:#009900">proxyTable:</span> {
<span style="color:#009900">'/api'</span><span style="color:#009900">:</span> {
<span style="color:#009900">target:</span> <span style="color:#009900">'http://XXXX'</span>,<span style="color:#008800">//</span>这里是服务器地址
<span style="color:#009900">changeOrigin:</span> <span style="color:#000088">true</span>,
<span style="color:#009900">pathRewrite:</span> {
<span style="color:#009900">'^/api'</span><span style="color:#009900">:</span> <span style="color:#009900">''</span>/<span style="color:#008800">/这里理解成用‘/api</span>’代替target里面的地址,后面组件中我们掉接口时直接用api代替 比如我要调用<span style="color:#009900">'http://40.00.100.100:3002/user/add'</span>,直接写‘/api/user/add’即可
}
}
},</code></span></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
注:修改了代理后,使用api一定要重新运行一下项目,要不然api就会挂在本地的8080的地址下
cors跨域处理机制
首先我们先了解一下使用cors时简单请求与非简单请求那些事:
<span style="color:#333333"><span style="color:#000000"><code>简单请求就是使用设定的请求方式请求数据
而非简单请求则是在使用设定的请求方式请求数据之前,先发送一个OPTIONS请求,看服务端是否允许客户端发送非简单请求<span style="color:#4f4f4f">.</span>只有<span style="color:#009900">"预检"</span>通过后才会再发送一次请求用于数据传输
<span style="color:#4f4f4f">*</span> 请求方式:HEAD,GET,POST
<span style="color:#4f4f4f">*</span> 请求头信息:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type 对应的值是以下三个中的任意一个
application/x-www-form-urlencoded
multipart/form-data
text/plain</code></span></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
同时满足以上两个条件的就是简单请求
使用cors跨域主要实在服务端配置请求头:
<span style="color:#333333"><span style="color:#000000"><code>Access-Control-Allow-Origin: http:<span style="color:#880000">//www.YOURDOMAIN.com // 设置允许请求的域名,多个域名以逗号分隔</span>
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS <span style="color:#880000">// 设置允许请求的方法,多个方法以逗号分隔</span>
Access-Control-Allow-Headers: Authorization <span style="color:#880000">// 设置允许请求自定义的请求头字段,多个字段以逗号分隔</span>
Access-Control-Allow-Credentials: <span style="color:#006666">true</span> <span style="color:#880000">// 设置是否允许发送 Cookies</span></code></span></span>
- 1
- 2
- 3
- 4
前端请求代码则普通ajax请求即可,没有特别的要求
说跨域是面试必问的问题之一应该没人反对吧,反正我每次面试都遇到过,不过之前只是简单的回答了有哪些方法,并没有说出个所以然来。这两天看了很多跨域相关的视频还有文档,以上是我对跨域的一些理解。