美文网首页
跨域问题

跨域问题

作者: 依然还是或者其他 | 来源:发表于2021-03-07 10:59 被阅读0次

跨域问题

前言

近期回顾自己之前弄的思维导图,这部分还可以再稍微细点,写点东西记录下

原因

跨域问题问题产生的原因是由于同源策略。
同源是指"协议+域名+端口"三者相同。
同源策略是浏览器的行为,是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。

JSONP

因为img,css,script等标签 不受同源策略影响,可以基于此策略,
利用script标签可以跨域的特点来发起跨域请求,后端返回一个函数,前端调用此函数,即完成的此次的请求

示例:

function jsonp() {
    var script = document.createElement('script');
    script.type = 'text/javascript';

    // 传参并指定回调执行函数为backFn
    script.src = 'http://localhost:8100/getUserInfo?uid=100&callback=backFn';
    document.head.appendChild(script);
}

// 回调执行函数
function backFn(res) {
    alert(JSON.stringify(res));
}

document.getElementById('btn_get_data').addEventListener('click',()=>{
    jsonp();
});

JSONP方案可以兼容各种浏览器,但只支持get请求

CORS

2014年1月16号CORS作为http协议的扩充部分正式发布,主要定义了客户端和服务端的沟通机制,也就是所谓的协议。
CORS需要浏览器和服务器同时支持。目前所有浏览器都支持该功能,IE浏览器不能低于IE10。

浏览器将CORS请求分成两类:

  • 简单请求(simple request)
  • 非简单请求(预检请求)(not-so-simple request)。

同时满足以下两大条件,就属于简单请求,否则就是非简单请求

(1) 请求方法是以下三种方法之一:

    HEAD
    GET
    POST
    
(2)HTTP请求头信息不超出以下几种字段:

    Accept
    Accept-Language
    Content-Language
    Last-Event-ID
    Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

简单请求
对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。

非简单请求
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

PostMessage

postMessage是html5引入的API可以更方便、有效、安全的解决这些问题。postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。

  • 页面和其打开的新窗口的数据传递
  • 多窗口之间消息传递
  • 页面与嵌套的iframe消息传递
  • 上面三个场景的跨域数据传递
postMessage(data,origin)方法接受两个参数

data: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
  origin: 协议+主机+端口号,也可以设置为"*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。

Websocket

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

var Socket = new WebSocket(url, [protocol] );

第一个参数 url, 指定连接的 URL。第二个参数 protocol 是可选的,指定了可接受的子协议。
基本用法

// 初始化一个 WebSocket 对象
var ws = new WebSocket("ws://localhost:9998/echo");

// 建立 web socket 连接成功触发事件
ws.onopen = function () {
  // 使用 send() 方法发送数据
  ws.send("发送数据");
  alert("数据发送中...");
};

// 接收服务端数据时触发事件
ws.onmessage = function (evt) {
  var received_msg = evt.data;
  alert("数据已接收...");
};

// 断开 web socket 连接成功触发事件
ws.onclose = function () {
  alert("连接已关闭...");
};

Cookie与iframe

如果两个网页一级域名相同,二级域名不同,游览器允许通过document.domain共享Cookie与iframe.

cookie的存储大小偏小

iframe 缺点:

1.会阻塞主页面的onload事件
2.和主页面共享连接池,而浏览器对相同域名的连接有限制,会影响页面并行加载
3.不利于SEO

由于1和2问题,最好通过js动态给iframe添加src属性来避免1、2问题

参考

彻底理解CORS跨域原理
解决postMessage跨域问题

相关文章

网友评论

      本文标题:跨域问题

      本文链接:https://www.haomeiwen.com/subject/axoeqltx.html