面试官:跨域有什么方法鸭?

149 阅读4分钟

老生长谈的问题,社区有很多总结的非常完善的好文。笔者在这记录一下自己的见解,有时间了再补充细节。

跨域原因

同源策略:协议、域名、端口号必须一致。

 同源策略限制了三个方面:
        1.dom层面:不同站点之间不能相互访问和操作dom 
        2.数据层面:不能获取不同源站点的cookie,LocalStorage、indexDB等数据
        3.网络层面:不能通过XMLHttpRequest向不同源站发送请求
        但是link、img、script标签都没有跨域限制

跨域分类

dom层面

1.片段标识符url中的hash
2.window.name
3.postMessage
4.document.domain 
document.domain + iframe 适用于主域名相同,子域名不相同
window.name + iframe 利用name值最长可以2M,并用不同页面或不同域名加载后依然存在的特性
location.hash + iframe 适用于通过C页面来实现与B页面通信的场景
以上三种都用不到
        postMessage
        html5新增的api 
        页面和新打开的窗口间数据传递
        多窗口之间数据传递
        页面与嵌套的iframe之间的数据传递
        上面三个场景之间的跨域传递
        postmessage接收两个参数
        参数一:发送的数据
        参数二:你要发送给谁就写谁的地址(协议+域名+端口),也可以设置为*,表示任意窗口,设置为/表示与当前窗口同源的窗口

网络层面

1.jsonp
2.cors
3.服务器代理
4.websocket
5.node中间件代理
jsonp
原理是通过添加一个script标签,向服务器请求jsonp数据,这样就不受同源政策限制。服务器收到请求后,将数据放在一个callback回调函数中传过来,比如axios
不过只支持get请求,且不安全。可能遇到xss攻击,不过它的好处时可以向老浏览器或不支持cors的网站请求数据

jsonp格式
[见笔者另一篇文章,写的很详细](https://juejin.cn/post/7000618779826716703)
cors
 cors分为简单请求和复杂请求
        另外cors请求默认不包含cookie以及http认证信息,如果需要包含cookie,需要满足几个条件
        服务器指定了 Access-Control-Allow-Credentials:true 
        开发者须在请求中打开withGredentials属性:xhr.withCredentials = true 
        Access-Control-Allow-Origin不要设置为星号,指定明确的与请求网页一致的域名,这样就不会把其他域名的cookie上传。
        
        
         简单请求:同时满足两个条件
        1.请求方法是head,get,post 
        2.请求头信息不超过以下几个字段
        AcceptAccept-LanguageContent-LanguageLast-Event-IdContent-Type值为三者之一application/x-www/form/urlencoded、multipart/form-data、text/plain
        
        浏览器直接发出cors请求,具体来说就是在头信息中增加origin字段,表示请求来源来自那个域(协议+域名+端口)服务器根据这个值决定是否同意请求。如果同意,返回的响应会多出以下响应头信息。
        Access-Control-Allow-OriginOrigin一致,这个字段必须
        Access-Control-Allow-Credentials: true 表示是否允许发送cookie 这个字段可选
        Access-Control-Expose-Headers: FooBar 指定返回其他字段的值 这个字段可选 
        Content-Type: text/html ;charset=utf-8 表示文档类型
        
        
         非简单请求,比如put或delete请求,或Content-Type为application/json,就是非简单请求
        非简单cors请求,正是请求前会发送一次options类型的查询请求,称为预检请求,询问服务器是否支持网页所在域名的请求,以及可以使用哪些头信息字段。只有收到肯定的答复、才会发起正式XMLHttpRequest请求,否则报错
        预检请求的方法是options,它的头信息中有几个字段
        origin 表示来自哪个域,这个字段是必须的
        Access-Control-Request-Method 列出cors请求会用到哪些http方法,这个字段是必须的
        Access-Control-Request-Headers 指定cors请求会额外发送的头信息字段,用逗号隔开
        options请求次数过多也会损耗性能,所以要尽量减少options请求,可以让服务器在请求返回头部添加
        Access-Control-Max-Age: Number 数字,单位是秒
        表示预检请求的返回结果可以被缓存多久,在这个时间范围内在请求就不需要预检了。不过这个缓存只对完全一样的url才会生效。
服务器代理Nginx

Node中间件代理;proxy

websocket
html5新增的通信协议,以ws或wss为协议前缀。

记录记录!