前端常见跨域解决方案(jsonp,cors,proxy,postMessage,webSocket)

这篇具有很好参考价值的文章主要介绍了前端常见跨域解决方案(jsonp,cors,proxy,postMessage,webSocket)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

跨域的几种解决方案:

一、JSONP(jsonp)

概念:

JSONP(JSON with Padding,填充式 JSON 或参数式 JSON)是一种通过

优点:
  • 简单易用
  • 兼容性好,支持各种浏览器
缺点:
  • 只能实现 GET 请求,无法实现 POST 等其他类型的请求
  • 安全性较低,容易受到 XSS 攻击
Eg:
为什么需要动态生成标签,而不是直接通过
原因有以下几点:
  1. 避免脚本注入攻击:如果直接将需要请求的数据以及回调函数名称写在

二、 CORS(Cross-Origin Resource Sharing)(cors)

概念:

CORS 是一种通过服务器设置响应头信息,允许指定域名的请求跨域访问资源,从而实现跨域资源共享的技术。具体而言,在服务端设置 Access-Control-Allow-Origin 响应头字段来指定允许的来源域名,以及其他相关的响应头信息。

优点:
  • 支持各种请求类型,包括 GET、POST、PUT 等
  • 安全性比 JSONP 较高,不容易受到 XSS 攻击
缺点:
  • 需要服务端进行配合,设置相应的响应头信息
  • 不是所有浏览器都支持 CORS(例如 IE8 和 IE9)
如何配置cors:

在服务端实现 CORS 跨域请求,需要配置相应的 HTTP 响应头。常见的响应头字段包括:

  • Access-Control-Allow-Origin:指定允许跨域请求的来源域名,如果希望允许所有来源域名,则可以设置为 *。
  • Access-Control-Allow-Methods:指定允许跨域请求的 HTTP 方法,如 GET、POST、PUT 等。多个方法之间使用逗号分隔。
  • Access-Control-Allow-Headers:指定允许跨域请求的自定义请求头,多个请求头之间使用逗号分隔。
  • Access-Control-Allow-Credentials:用于指示是否允许发送 Cookie 以及其他凭证信息到跨域请求中。如果设置为 true,则说明请求可以发送身份凭证。如果未设置或设置为 false,则不能发送凭证。

下面是一个 Node.js Express 框架的示例代码:

const express = require('express');
const app = express();

app.use(function(req, res, next) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.setHeader('Access-Control-Allow-Credentials', 'true');
  next();
});

// 处理路由和请求
// ...

app.listen(8080);

上述代码中,我们通过设置响应头来实现 CORS 跨域请求的支持。需要注意的是,如果设置了 Access-Control-Allow-Credentials 为 true,则在服务端也需要设置 req.header(‘Access-Control-Allow-Credentials’, ‘true’) 来响应凭证信息。此外,CORS 跨域请求还需要确保客户端和服务端的协议、域名和端口号均相同或允许跨域。

三、代理服务器(proxy)

概念:

代理服务器是一种通过在同一个域名下设置一个代理服务器,将需要跨域访问的请求先发送到代理服务器上,再由代理服务器向目标服务器发出请求,并将请求结果返回给客户端的技术。这样客户端就可以避免直接访问跨域服务器,从而可以绕开浏览器的同源策略。

优点:
  • 可以实现各种请求类型,包括 GET、POST、PUT 等
  • 安全性较高,不容易受到 XSS 攻击
缺点:
  • 需要额外的代理服务器来进行转发,增加了服务器的负担
  • 需要进行额外的配置和编码
举个常规的配置例子:

在 dva 项目中配置 proxy 可以通过修改 package.json 文件来实现。下面是一个详细的 dva 项目配置 proxy 的示例:

1. 在 dva 项目根目录下创建一个名为 setupProxy.js 的文件,用于配置代理。示例代码如下:
const proxy = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api', // 需要代理的请求前缀
    proxy({
      target: 'http://localhost:8080', // 设置代理目标地址
      changeOrigin: true, // 如果代理服务器和目标服务器协议、域名或端口不同,需要设置为 true
      pathRewrite: {
        '^/api': '' // 将请求路径的前缀 /api 去掉
      }
    })
  );
};

上述代码配置了一个代理,将所有以 /api 开头的请求转发到 http://localhost:8080/ 上,并将请求路径的前缀 /api 去掉。如果代理服务器和目标服务器协议、域名或端口不同,需要将 changeOrigin 设置为 true。

2. 在 package.json 文件中添加 “proxy” 字段,指定代理配置文件的路径。示例代码如下:
{
  "name": "my-dva-app",
  "version": "0.1.0",
  "dependencies": {
    // ...
  },
  "scripts": {
    // ...
  },
  "proxy": "http://localhost:3000/",
}

上述代码中,我们将 “proxy” 字段设置为 http://localhost:3000/,这意味着所有以 /api 开头的请求会被转发到 http://localhost:3000/api 上。

3. 在 dva model 中使用 fetch 或者 dva-loading 等异步请求方式时,只需要在 URL 中添加前缀 /api 即可。示例代码如下:
import { delay } from 'dva/saga';
import request from '../utils/request';

export default {

  namespace: 'example',

  state: {
    data: null,
  },

  effects: {
    *fetchData(_, { call, put }) {
      yield call(delay, 1000); // 模拟延迟
      const result = yield call(request, '/api/data'); // 请求地址为 /api/data
      yield put({
        type: 'saveData',
        payload: result.data,
      });
    },
  },

  reducers: {
    saveData(state, { payload }) {
      return {
        ...state,
        data: payload,
      };
    },
  },
};

上述代码中,我们在 effects 的 fetchData 方法中使用了 request 工具函数来发起一个 GET 请求,请求的地址为 /api/data,实际上会被代理转发到 http://localhost:8080/data 上。无论是 fetch 还是使用 dva-loading,只要在 URL 中加上 /api 前缀即可。

四、postMessage(postmessage)

概念:

postMessage 是一种在不同窗口之间通过 postMessage 方法发送消息,从而实现数据的跨域传输的技术。具体而言,在前端页面中使用 postMessage 方法来向目标域名发送一条消息,并在目标页面中通过监听 message 事件来接收并处理该消息。

优点:
  • 可以实现各种请求类型,包括 GET、POST、PUT 等
  • 安全性较高,不容易受到 XSS 攻击
缺点:
  • 需要浏览器支持 HTML5,不兼容 IE8 及以下版本的浏览器
  • 不支持传输大量数据
如何使用postMessage实现父窗口<–>子窗口通信:

在实际应用场景中,我们可能需要在不同的窗口/iframe 中进行通信,比如说,在一个页面中内嵌了多个 iframe 窗口,这些窗口之间需要进行数据交互。如果这些窗口处于同一个域名下,我们就可以通过 JavaScript 变量或者全局事件来进行通信,但是如果它们处于不同的域名下,我们就无法直接进行通信了。

这时候,就可以使用 postMessage 来完成跨域通信了。具体实现步骤如下:

子—>父
父窗口
  1. 在父窗口中创建一个 iframe 窗口,并指定它的 src 属性为要加载的子窗口页面。
  2. 在父窗口中监听子窗口发送的消息,并在处理函数中获取到消息内容,进行相应的处理。
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Parent Window</title>
</head>
<body>
  <!-- 创建一个 iframe 窗口 -->
  <iframe id="childWindow" src="http://example.com"></iframe>

  <script>
    // 监听子窗口发送的消息
    window.addEventListener('message', (event) => {
      // 首先判断消息来源是否合法
      if (event.origin === 'http://example.com') {
        // 获取消息内容并进行处理
        const message = event.data;
        console.log('Received message from child window:', message);
      }
    });
  </script>
</body>
</html>

在上面的代码中,我们在父窗口中创建了一个 iframe 窗口,并加载了一个跨域网站(http://example.com)。在父窗口中,我们使用 window.addEventListener() 方法监听 message 事件,当子窗口向父窗口发送消息时会触发该事件。在事件处理函数中,我们首先判断消息来源是否合法,如果合法,则获取到消息的内容并进行相应的处理。

子窗口
  1. 在子窗口中使用 window.parent 获取到父窗口对象,并向父窗口发送消息。
  2. 在子窗口中监听父窗口发送的消息,并在处理函数中获取到消息内容,进行相应的处理。
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Child Window</title>
</head>
<body>
  <script>
    // 向父窗口发送消息
    const targetOrigin = 'http://localhost:8080';
    const parentWindow = window.parent;
    parentWindow.postMessage('Hello, Parent Window!', targetOrigin);

    // 监听父窗口发送的消息
    window.addEventListener('message', (event) => {
      // 首先判断消息来源是否合法
      if (event.origin === 'http://localhost:8080') {
        // 获取消息内容并进行处理
        const message = event.data;
        console.log('Received message from parent window:', message);
      }
    });
  </script>
</body>
</html>

在上面的代码中,我们在子窗口中使用 window.parent 获取到父窗口对象,并使用 postMessage 方法向父窗口发送了一条消息。在最后一行代码中,targetOrigin 参数指定了目标窗口的域名和端口号,以确保消息能够被正确地发送到父窗口。在子窗口中,我们同样监听 message 事件,并在事件处理函数中获取到父窗口发送的消息内容。

父–>子:

要通过 postMessage 实现父窗口向子窗口发送数据,可以在父窗口中使用 iframe 元素的 contentWindow 属性获取到子窗口的 window 对象,然后调用该对象的 postMessage() 方法来发送消息。

具体实现步骤如下:

父窗口
  1. 在父窗口中创建一个 iframe 窗口,并指定它的 src 属性为要加载的子窗口页面。
  2. 在需要发送数据的时候,使用 contentWindow 属性获取到子窗口的 window 对象,并调用它的 postMessage() 方法发送消息。
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Parent Window</title>
</head>
<body>
  <!-- 创建一个 iframe 窗口 -->
  <iframe id="childWindow" src="http://example.com"></iframe>

  <script>
    const childWindow = document.getElementById('childWindow');

    // 发送数据给子窗口
    function sendDataToChild(data) {
      const targetOrigin = 'http://example.com';
      childWindow.contentWindow.postMessage(data, targetOrigin);
    }

    // 在需要发送数据的时候调用 sendDataToChild() 函数
    sendDataToChild('Hello, Child Window!');
  </script>
</body>
</html>

在上面的代码中,我们在父窗口中创建了一个 iframe 窗口,并加载了一个跨域网站(http://example.com)。在父窗口中,我们通过 document.getElementById() 方法获取到子窗口的 iframe 元素,然后使用 contentWindow 属性获取到子窗口的 window 对象。在 sendDataToChild() 函数中,我们调用该对象的 postMessage() 方法来向子窗口发送数据。

需要注意的是,在调用 postMessage() 方法时,第一个参数为要发送的数据,可以是任意类型的数据,比如字符串、数字、数组等;第二个参数为目标窗口的源(origin),可以指定一个字符串或者一个 URL 对象,用来控制数据发送的目标。如果不需要限制目标窗口,可以传入 ‘*’。具体使用时需要根据实际需求来设置。

综上所述,通过使用 postMessage,我们可以在不同的窗口/iframe 或者跨域时进行跨文档通信,实现数据的传递和交互。需要注意的是,在实际应用中,我们需要根据具体的需求和安全性考虑来选择合适的参数和方式进行配置和使用。

五、WebSocket(websocket)

概念:

WebSocket 是一种使用 HTTP 协议进行握手,建立一条持久性的连接,并通过该连接实现数据的实时推送和跨域传输的技术。
它允许客户端和服务器之间建立持久连接,使得双方可以实时地传递数据。相比于传统的 HTTP 请求-响应模式,WebSockets 可以减少网络延迟,提高数据传输的效率,同时也支持服务端向客户端主动推送数据。

WebSockets 协议实现了一个基于帧的消息传递机制,通过使用 WebSocket API,开发者可以方便地实现复杂的实时数据传输场景,比如在线聊天、多人游戏等等。

优点:
  • 建立的连接是持久性的,可以轻松地实现实时推送和通信
  • 支持双向数据传输
  • 安全性较高,不容易受到 XSS 攻击
缺点:
  • 需要浏览器和服务端同时支持 WebSocket 技术
  • 建立连接时需要进行额外的握手,增加了网络开销
如何使用 WebSockets:
服务器端

在服务器端,我们需要创建一个 WebSocket 的实例,并监听 connection 事件,在该事件处理函数中,可以获取到客户端连接的 WebSocket 对象,并通过它来处理后续的通信。

const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', (ws) => {
  console.log('A new client connected.');

  // 监听客户端发送的消息
  ws.on('message', (data) => {
    console.log('Received message from client:', data);
    // 发送消息给客户端
    ws.send('Hello, Client!');
  });
});

在上面的代码中,我们首先引入了 Node.js 的 WebSocket 模块,并创建了一个 WebSocket 的服务器实例,监听本地的 8080 端口。在 connection 事件处理函数中,我们可以获取到客户端连接的 WebSocket 对象,并通过它来监听 message 事件和发送消息。

客户端

在客户端,我们同样需要创建一个 WebSocket 的实例,并连接到服务器。在连接成功后,可以通过该实例来监听服务器发送的消息。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>WebSocket Example</title>
</head>
<body>
  <script>
    const socket = new WebSocket('ws://localhost:8080');

    // 监听连接成功事件
    socket.onopen = (event) => {
      console.log('Connected to server.');
      // 发送消息给服务器
      socket.send('Hello, Server!');
    };

    // 监听服务器发送的消息
    socket.onmessage = (event) => {
      console.log('Received message from server:', event.data);
    };
  </script>
</body>
</html>

在上面的代码中,我们创建了一个 WebSocket 的实例,并连接到服务器的地址(ws://localhost:8080)。在连接成功后,onopen 回调函数会被触发,此时我们可以通过 send() 方法向服务器发送消息。客户端还可以监听 onmessage 回调函数,从而获取服务器发送的消息内容。

综上所述,WebSocket 是一种实现双向通信的协议,其使用方式与传统的 HTTP 协议有一些不同,需要开发者进行相应的调整和适配。在实际应用中,我们需要根据具体的需求和场景来选择合适的协议和工具来实现数据通信。文章来源地址https://www.toymoban.com/news/detail-722293.html

到了这里,关于前端常见跨域解决方案(jsonp,cors,proxy,postMessage,webSocket)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • nginx设置add_header失效 配置cors跨域失效无效的解决方案

    希望对大家有帮助,有用的话记得点个赞评个论,让俺知道这个法子可以帮助到大家哟!(虽然我这个法子很野) 最近在完成一个项目,后端API地址和前端地址不一致,这就涉及到了跨域的问题。 由于服务端加了一层Nginx作为反代,所以很自然的想到要去 .conf 配置文件中 加

    2024年02月12日
    浏览(43)
  • 常见的跨域解决方案

    常见的跨域解决方案: 跨域问题可以分为两种情况: 前端跨域和后端跨域 。以下是针对这两种情况的跨域解决方案: 前端跨域解决方案: JSONP: 适用于前端向不同域名下的服务器请求数据,通过添加回调函数名称来实现跨域数据获取。 CORS: 当前端向服务器请求数据时,

    2024年02月12日
    浏览(49)
  • 跨域的五种最常见解决方案

    在开发Web应用程序时,一个常见的问题是如何处理跨域请求。跨域请求是指来自不同源的请求,这些请求可能会受到浏览器的限制而不能被正常处理。在这篇文章中,我们将探讨跨域请求的常见解决方案,并了解每种解决方案的优缺点。 一、JSONP JSONP是一种常见的跨域请求解

    2024年02月01日
    浏览(49)
  • 跨域介绍及Java中常见的跨域解决方案

    跨域(Cross-Origin)指的是在浏览器中,由于安全策略的限制,当前网页的 JavaScript 代码无法直接访问不同源(协议、域名、端口)的资源。这意味着如果网页尝试通过 AJAX、Fetch 或 WebSocket 等方式向不同源的服务器发送请求,浏览器会阻止这些请求,从而避免潜在的安全风险。

    2024年02月07日
    浏览(41)
  • 最常见的六种跨域解决方案

    前言:什么是跨域? JSONP CORS 搭建Node代理服务器 Nginx反向代理 postMessage Websocket 总结 跨域就是当在页面上发送ajax请求时, 由于浏览器同源策略的限制,要求当前页面和服务端必须同源,也就是协议、域名和端口号必须一致 。 如果协议、域名和端口号中有其中一个不一致,

    2024年01月25日
    浏览(51)
  • 前端面试:【跨域与安全】跨域问题及解决方案

    嗨,亲爱的Web开发者!在构建现代Web应用时,跨域问题和安全性一直是不可忽视的挑战之一。本文将深入探讨跨域问题的背景以及解决方案,以确保你的应用既安全又能与其他域名的资源进行互操作。 1. 什么是跨域问题? 跨域问题指的是在Web开发中,浏览器的同源策略(S

    2024年02月11日
    浏览(65)
  • 前端的8种跨域解决方案

    在前端开发中,常见的跨域解决方案有以下8种: JSONP(JSON with Padding):利用 script 标签的跨域特性,通过动态创建 script 标签,请求一个带有回调函数的接口,服务器返回的数据会作为回调函数的参数传入,从而实现跨域请求。 CORS(Cross-Origin Resource Sharing):通过服务器设

    2024年02月09日
    浏览(46)
  • WEB攻防通用漏洞&跨域CORS资源&JSONP回调&域名接管劫持

    目录 一、同源策略(SOC) 二、跨域资源(COSP) 三、回调跨域(JSOP) 四、CORS资源跨域-敏感页面原码获取 五、JSONP 回调跨域-某牙个人信息泄露 六、子域名劫持接管 同源策略 (SOP)-“ 同源 ” 包括三个条件:同协议、同域名、同端口。 会检测数据包的来源在哪里,进而来判

    2024年02月01日
    浏览(66)
  • html前端跨域问题的解决方案

    前言: 在前端发出Ajax请求的时候,有时候会产生跨域问题,报错如下: Access to XMLHttpRequest at ‘http://127.0.0.1/api/post’ from origin ‘null’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. 针对以上问题,本文提供两种解决方案,CORS中间件和

    2023年04月22日
    浏览(86)
  • 前端笔记 ---- Chrome 浏览器不能跨域访问解决方案

    1. 需求场景 Chrome 浏览器开发 H5 进行接口联调时,浏览器不允许跨域访问; 想通过浏览器设置,不使用代理等,浏览器可以进行跨域访问。 2. 报错图片 3. 解决方案 3.1 获取Chrome 浏览器安装位置 3.2 设置允许跨域和不验证证书 3.3 cmd 执行设置命令 3.4 组成完整命令 3.5 cmd 运行命

    2024年02月15日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包