深入理解跨域(看完就会)

什么是跨域 ?

跨域是指在浏览器中,当前网页从不同域名、协议或端口请求资源时,出现的安全限制问题。通常,这种限制被称为同源策略,它是浏览器的一种安全机制,用于防止恶意网站读取另一个网站的数据。

同源策略

同源策略规定,只有当协议、域名和端口三者都相同的时候,才允许进行请求。

例如:

· 同源:http://www.baidu.comhttp://www.baidu.com:80

· 不同源:http://www.baidu.comhttps://www.baidu.com (协议不同)

常见的跨域场景

  1. AJAX 请求不同源的 API。
  2. 通过 <script> 标签加载不同源的脚本文件(虽然这种方式不受同源策略限制,但存在其他安全问题)。
  3. 使用 iframe 加载不同源的页面。
  4. WebSocket 连接不同源的服务。

跨域解决方法

1. JSONP

JSONP (JSON with Padding) 是一种通过动态添加 <script> 标签来跨域获取数据的方式。服务器返回的不是 JSON 格式的数据,而是一个 JavaScript 函数的调用。

客户端代码:

function handleResponse(response) {
  console.log(response);
}

var script = document.createElement('script');
script.src = 'http://example.com/data?callback=handleResponse';
document.head.appendChild(script);

服务器响应:

handleResponse({"message": "Hello, world!"});

优点:

  • 简单易用,支持所有浏览器。
  • 不受同源策略限制。

缺点:

  • 仅支持 GET 请求。
  • 存在安全风险,容易被利用进行 XSS 攻击。
2. CORS

CORS (Cross-Origin Resource Sharing) 是一种允许服务器指示哪些来源站点可以访问资源的机制。服务器通过设置 HTTP 头来实现跨域访问。

服务器设置:

Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type


 

客户端请求:

fetch('http://example.com/data', {
  method: 'GET',
  credentials: 'include'
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

优点:

  • 安全性高,可以灵活控制允许的跨域请求。
  • 支持多种 HTTP 方法。

缺点:

  • 需要服务器配置支持。
  • 对于复杂请求会进行预检(preflight)请求,增加了开销。
3. 代理服务器

通过在同源服务器上设置代理,转发请求到目标服务器,解决跨域问题。

客户端请求:

fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));


 

代理服务器配置(例如使用 Node.js + Express):

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

app.use('/api', (req, res) => {
  const url = 'http://example.com' + req.url;
  req.pipe(request(url)).pipe(res);
});

app.listen(3000, () => {
  console.log('Proxy server listening on port 3000');
});

优点:

  • 对客户端透明,配置简单。
  • 支持各种请求方法和头信息。

缺点:

  • 增加了服务器负载。
  • 需要维护代理服务器。
4. WebSocket

WebSocket 是一种全双工通信协议,可以用来在浏览器和服务器之间建立持久连接,允许跨域通信。

服务器端(Node.js):

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

wss.on('connection', ws => {
  ws.on('message', message => {
    console.log('received:', message);
  });
  ws.send('Hello from server');
});


 

客户端:

const socket = new WebSocket('ws://example.com:8080');

socket.onopen = function() {
  socket.send('Hello from client');
};

socket.onmessage = function(event) {
  console.log('Message from server:', event.data);
};

优点:

  • 支持实时双向通信。
  • 不受同源策略限制。

缺点:

  • 需要服务器和客户端都支持 WebSocket 协议。
  • 存在一定的学习和实现成本。
5. 使用 Vue CLI 的代理配置

Vue CLI 提供了开发服务器代理选项,可以轻松地将 API 请求代理到不同的服务器。这是最常见和最简单的方法。

步骤:

  1. 在 Vue 项目的根目录下,找到 vue.config.js 文件。如果没有这个文件,可以创建一个。
  2. 在 vue.config.js 中添加以下代码:
module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'http://example.com',  // 目标服务器的地址
        changeOrigin: true,  // 是否改变源
        pathRewrite: { '^/api': '' },  // 将请求路径中的 /api 替换为空字符串
      },
    },
  },
};


 

说明:

  • '/api' 是你在前端代码中使用的路径前缀。
  • target 是你要代理的目标服务器。
  • changeOrigin 设置为 true,表示代理时修改请求头中的 Host 为目标地址。
  • pathRewrite 是可选的,用于重写路径,比如将 /api 前缀去掉。

使用示例:

前端代码中调用 API 时:

axios.get('/api/data')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error(error);
  });

总结

跨域是前端开发中常见的问题,通过不同的技术和方法可以有效地解决。选择合适的解决方案需要考虑安全性、兼容性和具体业务需求。CORS 是目前最常用的方法,JSONP 适用于简单的 GET 请求,而代理服务器和 WebSocket 则可以用于更复杂的跨域通信需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rookie WLK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值