【潜意识java】前后端跨域问题及解决方案

简介: 本文深入探讨了跨域问题及其解决方案。跨域是指浏览器出于安全考虑,限制从一个域加载的网页请求另一个域的资源。

 目录

什么是跨域?

浏览器的同源策略

跨域的常见场景

跨域的解决方案

1. CORS(跨域资源共享)

CORS 的实现原理:

常见 CORS 相关响应头:

示例:前端发送 CORS 请求

服务器端配置:

适用场景:

2. JSONP(JSON with Padding)

原理:

示例:

限制:

适用场景:

3. 代理服务器

实现原理:

示例:

适用场景:

4. WebSocket

原理:

示例:

适用场景:

总结


image.gif 编辑

请代表个人观点,跨域问题我还是有经验的!

在现代 web 开发中,前后端分离架构越来越普及,前端和后端通常部署在不同的域名或端口下。这种情况就涉及到一个常见的问题——跨域问题(Cross-Origin Resource Sharing,CORS)。跨域问题指的是浏览器出于安全考虑,限制从一个域加载的网页去请求另一个域的资源。为了让前后端可以顺利通信,我们需要解决跨域问题。

本文将深入探讨跨域的概念、跨域产生的原因,以及当前几种主流的解决方案,帮助你快速实现前后端跨域通信。

image.gif 编辑

什么是跨域?

跨域指的是在 Web 页面中发起的请求,目标域和请求的源域(即当前页面所在的域)不一致。举个例子,假设前端页面在 http://localhost:3000 上,而后端接口部署在 http://api.example.com,前端页面向后端发起请求时,就会产生跨域问题。

浏览器的同源策略

浏览器的同源策略(Same-Origin Policy,SOP)是为了解决潜在的安全问题而设计的,目的是防止恶意网站利用脚本读取其他网站的敏感信息。同源策略规定,只有在协议、域名、端口三者完全相同的情况下,浏览器才允许跨文档(iframe、XMLHttpRequest)进行资源请求。否则,就会触发跨域限制。

image.gif 编辑

跨域的常见场景

  1. 前后端分离开发:前端和后端分别部署在不同的域名、端口或服务器上。
  2. 第三方服务调用:比如调用第三方的 API(如支付、地图等服务),由于不同服务域名不同,容易出现跨域问题。
  3. 静态资源的跨域访问:当前端从外部 CDN 服务器加载资源时,涉及到不同域名的请求,也会面临跨域限制。

跨域的解决方案

解决跨域的方案主要有以下几种:CORS(跨域资源共享)、JSONP代理服务器WebSocket 等。接下来,我们将分别探讨每种方案的原理和适用场景。

1. CORS(跨域资源共享)

CORS 是一种浏览器的标准化机制,允许浏览器跨域请求资源。CORS 的核心思想是在服务器端设置 HTTP 头部信息,告知浏览器哪些请求是被允许的。

CORS 的实现原理:

  • 请求阶段:当浏览器向服务器发送跨域请求时,它会附带一些特殊的头部信息(如 Origin),用于指示请求来源。
  • 服务器响应阶段:服务器根据请求头中的 Origin 字段,决定是否允许跨域请求。如果允许,服务器会在响应头中添加 Access-Control-Allow-Origin 等 CORS 相关的 HTTP 头部,告诉浏览器该请求是安全的,可以进行跨域操作。

常见 CORS 相关响应头:

  • Access-Control-Allow-Origin:指定允许哪些源可以访问该资源,可以是具体的域名(如 http://localhost:3000),或者 * 表示允许所有域名。
  • Access-Control-Allow-Methods:指定允许的 HTTP 方法,如 GETPOSTPUTDELETE 等。
  • Access-Control-Allow-Headers:指定允许哪些请求头信息。
  • Access-Control-Allow-Credentials:指定是否允许携带认证信息(如 Cookies、HTTP 认证等)。

示例:前端发送 CORS 请求

fetch('http://api.example.com/data', {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json'
  },
  credentials: 'include' // 如果需要带上 Cookies 等认证信息
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

image.gif

服务器端配置:

image.gif 编辑

Express 为例,使用 cors 中间件来启用 CORS 支持:

const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
  origin: 'http://localhost:3000',  // 允许的域名
  methods: ['GET', 'POST'],        // 允许的请求方法
  allowedHeaders: ['Content-Type'] // 允许的请求头
}));
app.get('/data', (req, res) => {
  res.json({ message: 'Hello from server' });
});
app.listen(5000, () => {
  console.log('Server is running on port 5000');
});

image.gif

适用场景:

  • 当你的前后端都能控制时,推荐使用 CORS。
  • 对于现代 Web 应用,CORS 是最标准和推荐的解决方案。

2. JSONP(JSON with Padding)

JSONP 是一种绕过浏览器同源策略的老方法,通常用于解决跨域请求问题。其原理是通过动态创建 <script> 标签来加载数据,因为 <script> 标签不受同源策略限制。

原理:

  • 客户端在请求时传递一个回调函数名称,服务器返回的数据是该回调函数的执行代码,数据作为参数传递给回调函数。
  • 由于 <script> 标签不受跨域限制,浏览器能够成功执行来自其他域的数据。

示例:

前端代码:

function handleResponse(data) {
  console.log(data); // 处理返回的数据
}
const script = document.createElement('script');
script.src = 'http://api.example.com/data?callback=handleResponse';
document.body.appendChild(script);

image.gif

服务器返回的数据:

handleResponse({ message: 'Hello from server' });

image.gif

限制:

  • JSONP 只能支持 GET 请求,不能处理 POST 请求。
  • 安全性较差,容易受到 XSS 攻击,因此不推荐用于处理敏感数据。

适用场景:

适合用来请求一些公开的 API 服务,特别是一些老旧的、没有支持 CORS 的服务。

image.gif 编辑

3. 代理服务器

代理服务器是一种简单而常见的跨域解决方案。通过配置代理服务器,将前端的请求代理到后端服务器。前端向代理服务器发起请求,代理服务器再转发请求到后端服务。由于浏览器并不直接与目标域进行交互,跨域问题得以避免。

实现原理:

  1. 前端请求代理服务器,代理服务器再向后端转发请求。
  2. 代理服务器和后端之间并不会受到浏览器的同源策略限制。

示例:

假设你的前端应用在 http://localhost:3000,而后端在 http://localhost:5000。你可以通过配置 Webpack 的开发服务器或其他代理服务器来解决跨域问题。

Webpack 配置(webpack.config.js):

module.exports = {
  devServer: {
    proxy: {
      '/api': 'http://localhost:5000'
    }
  }
};

image.gif

在这个配置下,前端请求 http://localhost:3000/api,实际上会被代理到 http://localhost:5000/api,避免了浏览器的跨域问题。

适用场景:

  • 适用于前后端开发环境,尤其是开发阶段。
  • 适用于没有 CORS 支持的后端服务。

4. WebSocket

WebSocket 是一种网络协议,能够实现全双工通信。与 HTTP 请求不同,WebSocket 不受同源策略的限制,因此在跨域场景下也可以使用。

原理:

  • WebSocket 在客户端与服务器之间建立一个持久化的连接,双方可以随时发送数据,支持双向通信。

示例:

前端代码:

const socket = new WebSocket('ws://api.example.com/socket');
socket.onopen = () => {
  console.log('WebSocket connection established');
  socket.send('Hello Server');
};
socket.onmessage = (event) => {
  console.log('Received message:', event.data);
};

image.gif

后端(以 Node.js 为例):

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', ws => {
  ws.on('message', message => {
    console.log('received: %s', message);
  });
  ws.send('Hello Client');
});

image.gif

适用场景:

  • 实时应用,比如在线聊天、实时游戏、股票行情等。
  • 不受同源策略限制,可以跨域连接。

总结

image.gif 编辑

跨域问题是现代 Web 开发中的常见挑战,但幸运的是有多种方式可以解决。CORS 是最标准和推荐的方式,适用于大多数场景;JSONP 是一种历史悠久的解决方案,适用于公开的 API 服务;代理服务器 解决方案适合开发阶段使用,尤其是前后端分离时;而 WebSocket 提供了实时的双向通信,适合用于实时应用。

image.gif 编辑


相关文章
|
25天前
|
存储 Java 开发者
【潜意识Java】深入详细理解分析Java中的toString()方法重写完整笔记总结,超级详细。
本文详细介绍了 Java 中 `toString()` 方法的重写技巧及其重要
47 10
【潜意识Java】深入详细理解分析Java中的toString()方法重写完整笔记总结,超级详细。
|
3天前
|
网络协议 Java Shell
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
23 7
|
2天前
|
缓存 Java 应用服务中间件
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
22 5
|
25天前
|
算法 搜索推荐 Java
【潜意识Java】深度解析黑马项目《苍穹外卖》与蓝桥杯算法的结合问题
本文探讨了如何将算法学习与实际项目相结合,以提升编程竞赛中的解题能力。通过《苍穹外卖》项目,介绍了订单配送路径规划(基于动态规划解决旅行商问题)和商品推荐系统(基于贪心算法)。这些实例不仅展示了算法在实际业务中的应用,还帮助读者更好地准备蓝桥杯等编程竞赛。结合具体代码实现和解析,文章详细说明了如何运用算法优化项目功能,提高解决问题的能力。
55 6
|
25天前
|
SQL Java 数据库连接
【潜意识Java】MyBatis中的动态SQL灵活、高效的数据库查询以及深度总结
本文详细介绍了MyBatis中的动态SQL功能,涵盖其背景、应用场景及实现方式。
88 6
|
25天前
|
算法 Java C++
【潜意识Java】蓝桥杯算法有关的动态规划求解背包问题
本文介绍了经典的0/1背包问题及其动态规划解法。
44 5
|
25天前
|
Java 应用服务中间件 API
【潜意识Java】javaee中的SpringBoot在Java 开发中的应用与详细分析
本文介绍了 Spring Boot 的核心概念和使用场景,并通过一个实战项目演示了如何构建一个简单的 RESTful API。
38 5
|
25天前
|
人工智能 自然语言处理 搜索推荐
【潜意识Java】了解并详细分析Java与AIGC的结合应用和使用方式
本文介绍了如何将Java与AIGC(人工智能生成内容)技术结合,实现智能文本生成。
49 5
|
25天前
|
SQL Java 数据库连接
【潜意识Java】Java中JDBC过时方法的替代方案以及JDBC为什么过时详细分析
本文介绍了JDBC中一些常见过时方法及其替代方案。
39 5

热门文章

最新文章