• 前端解决跨域访问的八种实现方式
  • 发布于 2个月前
  • 245 热度
    0 评论
跨域是指在同一网站下,由于浏览器的安全机制,不能直接访问其他网站的数据。而前端开发中,由于业务的需要,经常需要和其他网站进行数据交互。因此,解决跨域问题成为了前端开发必备的技能。本文将详细介绍跨域的八种实现方式,以及它们的使用场景、优缺点。

一、JSONP
JSONP 是一种利用 <script> 标签进行跨域请求的方式。它的原理是在请求地址中添加一个回调函数名,服务端在返回数据时会将数据作为参数传入该回调函数中,并返回给客户端。客户端则可以通过定义这个回调函数来处理返回的数据。

示例代码:
// 堆代码 duidaima.com
function jsonp(url, callback) {
  const script = document.createElement('script');
  script.src = `${url}&callback=${callback}`;
  document.body.appendChild(script);
  window[callback] = function(data) {
    document.body.removeChild(script);
    delete window[callback];
    callback(data);
  }
}

jsonp('https://www.duidaima.com/data', function(data) {
  console.log(data);
});
使用场景:
1.只支持 GET 请求。
2.能够支持跨域请求,但只能处理 JSON 数据。
3.适用于数据量较小、不需要特别保密的场景。

优缺点
优点:实现简单、支持跨域请求。
缺点:只能处理 JSON 数据、无法处理错误信息、存在安全风险。

二、CORS
CORS 是一种官方推荐的跨域解决方案。它的原理是在发送请求时,服务端在响应头中添加一个 Access-Control-Allow-Origin 字段,标识允许哪个源进行访问。客户端则可以通过设置 withCredentials 属性来携带认证信息,以及在响应头中获取对应的字段。

示例代码:
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.duidaima.com/data');
xhr.withCredentials = true;
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) {
    console.log(xhr.responseText);
  }
};
xhr.send();
使用场景:
1.支持 GET、POST 等类型的请求。
2.能够支持跨域请求,同时支持多种数据类型。
3.适用于大部分的场景。

优缺点:
优点:能够支持跨域请求、支持多种数据类型。
缺点:需要服务端配合设置响应头、性能稍低。

三、WebSocket
WebSocket 是一种双向通信协议,它可以在浏览器和服务端之间建立一个持久化的连接,以实现实时通信。由于它是基于 HTTP 协议的,因此支持跨域请求。
示例代码:
const ws = new WebSocket('ws://duidaima.com/socket');
ws.onmessage = function(event) {
  console.log(event.data);
};
使用场景:
1.可以实现双向通信、实时更新。
2.适用于聊天室、游戏等实时性较高的场景。

优缺点:
优点:能够实现双向通信、实时更新。
缺点:需要服务端配合实现、只能处理文本数据、不稳定。

四、postMessage
postMessage 是 HTML5 中新增的一种跨窗口通信机制,它可以在不同窗口、甚至不同域名之间进行数据传递。它的原理是通过调用 window.postMessage() 方法,在目标窗口中触发一个message 事件,从而实现数据的传递。

示例代码:
// 发送消息
window.parent.postMessage('hello', 'https://www.duidaima.com');

// 接收消息
window.addEventListener('message', function(event) {
  if (event.origin === 'https://www.duidaima.com') {
    console.log(event.data);
  }
});
使用场景:
可以进行不同窗口、不同域名之间的数据传递。
适用于嵌套页面、多窗口通信等场景。

优缺点
优点:可以进行不同窗口、不同域名之间的数据传递。
缺点:需要进行安全性检查、可能存在 XSS 攻击风险。

五、nginx 反向代理
通过配置 nginx 的反向代理,可以实现对目标地址的访问,并将响应返回给客户端。由于是在服务端进行请求,因此不会受到浏览器的同源策略限制。

示例代码:
location /api/ {
  proxy_pass https://www.duidaima.com/data/;
}
使用场景:
1.用于解决前端直接访问跨域 API 的问题。
2.适用于请求量较大、需要保密的场景。

优缺点:
优点:能够支持跨域请求、保护了 API 的安全性。
缺点:需要配置服务器,增加了服务器端的压力。

六、HTML5 XHR2
HTML5 中新增的 XHR2 对象,支持跨域请求,并且可以处理二进制数据和进度信息。

示例代码:
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.duidaima.com/data');
xhr.responseType = 'blob';
xhr.onload = function() {
  const reader = new FileReader();
  reader.onloadend = function() {
    console.log(reader.result);
  };
  reader.readAsText(xhr.response);
};
xhr.send();
使用场景:
1.支持跨域请求,能够处理二进制数据和进度信息。
2.适用于需要上传、下载文件等场景。

优缺点:
优点:支持跨域请求、能够处理二进制数据和进度信息。
缺点:浏览器兼容性不一、需要服务端配合设置响应头。

七、document.domain
通过设置 document.domain 的值,可以实现不同子域名之间的跨域通信。但是该方式只适用于主域名相同、子域名不同的情况下。

示例代码:
// 在 A 页面中设置
document.domain = 'duidaima.com';
// 在 B 页面中设置
document.domain = 'duidaima.com';
使用场景:
1.只适用于主域名相同、子域名不同的情况下。
2.适用于不同子域名之间进行数据传递的场景。

优缺点:
优点:实现简单、不需要浏览器支持。
缺点:只适用于主域名相同、子域名不同的情况下。

八、iframe
通过在页面中插入一个 iframe,可以在其中加载目标页面,从而实现跨域通信。但是该方式存在一些安全问题,容易遭受 CSRF 攻击。
示例代码:
<iframe src="https://www.duidaima.com"></iframe>
使用场景:
适用于嵌套页面、跨域数据传输等场景。

优缺点:
优点:能够实现跨域通信。
缺点:存在安全风险、容易遭受 CSRF 攻击。
用户评论