在Java项目中跨域的解决办法

目录

一、跨域

1、什么是跨域

二、跨域的解决方案CROS

1、CROS简介

2、在项目中的具体实施

1.使用@CrossOrigin注解

三、nignx反向代理解决跨域

1、什么是反向代理

2、nginx解决跨域


一、跨域

1、什么是跨域

跨域是由于浏览器的同源策略导致的限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。

如果跨域调用,会出现如下错误:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'Node Exporter' is therefore not allowed access. The response had HTTP status code 400.

如果我们采用的是前后端分离的编程方式,前端和后端必定存在跨域问题。

二、跨域的解决方案CROS

1、CROS简介

CORS 是一个 W3C 标准,全称是"跨域资源共享"(Cross-origin resource sharing)。CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE 浏览器不能低于 IE10。它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制。整个 CORS 通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS 通信与同源的 AJAX 通信没有差别,代码完全一样。浏览器一旦发现 AJAX 请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨源通信。

请求过程如下图:

Preflight Request:

1、预检请求(Preflight Request)

当浏览器发现跨域请求时,会首先发送一个 OPTIONS 请求给服务器,询问服务器是否允许该跨域请求。这称为预检请求。

  • PreflightResponse:

2、服务器响应头

如果服务器允许该跨域请求,就会在响应中添加相关的 HTTP 头信息,如:

  • Access-Control-Allow-Origin:指定允许跨域访问的源(可以是具体的域名或 * 表示允许所有域)。
  • Access-Control-Allow-Methods:允许的请求方法,如 GET、POST、PUT、DELETE 等。
  • Access-Control-Allow-Headers:允许客户端发送的自定义请求头。
  • Access-Control-Allow-Credentials:指示是否允许携带 Cookie 等凭证信息。

3、正式请求

预检请求得到允许后,浏览器才会发出正式的跨域请求。通过这种机制,服务器可以明确告知浏览器哪些跨域请求是被允许的,从而有效地解决跨域问题。

2、CROS解决跨域

1.使用@CrossOrigin注解

Spring Boot 提供了 @CrossOrigin 注解,可以直接在 Controller 类或方法上配置跨域支持,而不需要全局配置。下面是一个示例代码:

java 复制代码
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
// 在类上使用 @CrossOrigin 注解,允许所有来源的跨域请求
@CrossOrigin(origins = "*", allowedHeaders = "*", methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE, RequestMethod.OPTIONS})
public class MyController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello, Cross-Origin!";
    }
}

说明:

  • @CrossOrigin直接在 Controller 类或方法上使用该注解,可以指定允许跨域的来源、请求方法、请求头以及是否允许携带凭证(如 Cookie)。

  • origins指定允许的请求来源,这里使用 "*" 表示允许所有来源。生产环境建议指定具体的域名以提高安全性。

  • allowedHeaders指定允许客户端发送的请求头信息,这里也使用 "*" 表示允许所有请求头。

  • methods指定允许的 HTTP 请求方法,比如 GET、POST 等。

这样配置后,当客户端从其他域名发起请求时,Spring Boot 会自动在响应头中添加相应的 CORS 信息,从而允许跨域访问。

三、nignx反向代理解决跨域

1、什么是反向代理

反向代理是一种代理服务器,其主要作用是在客户端与后端服务器之间充当中介。

具体来说:

  • 请求转发:客户端发送请求到反向代理服务器,反向代理服务器再将请求转发到后端真实的服务器上。处理完成后,后端服务器把响应返回给反向代理服务器,再由反向代理服务器返回给客户端。

  • 隐藏后端信息:客户端只与反向代理服务器交互,并不知道实际的后端服务器地址,这有助于提高系统的安全性和可维护性。

  • 负载均衡:反向代理可以根据一定的规则(如轮询、最小连接数等)将请求分发到多个后端服务器,从而实现负载均衡,提高系统的并发处理能力。

  • 缓存和加速:反向代理服务器可以缓存后端服务器的响应,减少后端服务器的压力,同时提高响应速度。

  • 安全防护:反向代理可以作为一道安全防线,屏蔽真实的后端服务器,防止直接攻击后端服务。

举个例子,Nginx 常被用作反向代理服务器。假设你有一个网站,域名为example.com,后端服务器地址为 192.168.1.100。你可以配置 Nginx 接收所有来自 example.com 的请求,并将请求转发到后端服务器。当用户访问 http://example.com 时,他们实际上是在与 Nginx 交互,而 Nginx 再将请求传递给 192.168.1.100 来获取数据。

这种方式不仅可以解决跨域问题(通过同一个域名代理后端服务),还可以提供负载均衡、安全防护、缓存加速等多种好处。

2、nginx解决跨域

通过 Nginx 反向代理,将前端请求伪装成同源请求,从而绕过浏览器的同源策略限制。这样,前端所有请求均指向同一个域名(如 your-domain.com),而 Nginx 内部再将请求转发到实际的后端服务。

示例:

java 复制代码
server {
    listen 80;
    server_name your-domain.com;

    location /api/ {
        # 将所有 /api/ 请求转发到后端服务器
        proxy_pass http://backend_server/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
  • 反向代理原理

    前端请求 http://your-domain.com/api/xxx 时,由 Nginx 将请求转发到后端服务器(例如 http://backend_server/xxx)。

    由于浏览器认为请求目标依然是 your-domain.com,因此不会触发跨域问题。

  • 优势

    除了解决跨域问题外,反向代理还可以隐藏后端服务器信息、实现负载均衡和缓存加速等功能。

相关推荐
froginwe114 分钟前
R 基础运算
开发语言
醉城夜风~4 分钟前
[数据结构]堆详解
开发语言·数据结构
用户611881615196223 分钟前
Java基础面试题
java
17´31 分钟前
Qt从入门到入土(八) -打包Qt程序
开发语言·c++·qt
AI+程序员在路上32 分钟前
QT显示网页控件QAxWidget、QWebEngineView及区别
开发语言·qt
南玖yy37 分钟前
C语言柔性数组深度解析:动态内存管理的艺术
c语言·开发语言·柔性数组
2301_764441331 小时前
python实现的生态模拟系统
开发语言·python·pygame
DavidSoCool1 小时前
Elasticsearch Java API Client [8.17] 使用
java·大数据·elasticsearch
无世世1 小时前
【Java从入门到起飞】面向对象编程(高级)
java·开发语言
q567315231 小时前
使用CPR库编写的爬虫程序
开发语言·爬虫·golang·音视频