lotus

贵有恒何必三更眠五更起 最无益只怕一日曝十日寒

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

1.   什么是 跨域请求 

跨域请求是指浏览器向不同域名的服务器发送请求,例如从http://www.a.comhttp://www.b.com发送请求。由于浏览器的同源策略,跨域请求会受到限制,需要服务器端或客户端进行处理。同源策略是为了保证用户信息的安全,防止恶意的网站窃取数据。

举例说明:

假设运行在http://www.a.com的网页应用想要访问http://www.b.com/data.json的资源。网页中可能包含类似于下面的 JavaScript 代码:

const xhr = new XMLHttpRequest();
const url = 'http://www.b.com/data.json';
xhr.open('GET', url);
xhr.onreadystatechange = someHandler;
xhr.send();

这段代码会发起一个跨域请求,因为请求的 URL 的协议、域名和端口与当前页面的 URL 不同。如果服务器端没有设置允许跨域访问的响应头,浏览器就会拒绝接收响应,并在控制台报错。

 

 

浏览器安全的基石是「同源策略」(same-origin policy)。同源即:

  • 协议相同
  • 域名(主机名)相同
  • 端口相同

 

同源政策是为了保证用户信息的安全,防止恶意的网站窃取数据。一个页面:

  • 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
  • 无法接触非同源网页的 DOM
  • 无法向非同源地址发送 AJAX 请求(可以发送,但浏览器会拒绝接受响应)

一个源访问另一个源的资源时即为「跨源」,最常见的跨源场景是域名不同,即常说的“跨域”。有时候我们不得不进行跨域请求,那么应该如何解决呢?目前主要有以下方案:

  • JSONP(JSON with Padding)
  • CORS(Cross-Origin Resource Sharing)
  • Websocket
  • 在 nginx 等反向代理服务器中设置为同一域名

 

本文介绍了几种在JAVA后端实现跨域请求的方法。

2 . JAVA后端实现跨域请求

2.1  方法一:CORS

CORS(Cross-Origin Resource Sharing)是一种标准的跨域解决方案,它允许服务器在响应头中添加一些特定的字段,来告诉浏览器可以接受哪些域名的请求,以及可以使用哪些方法和头部信息。浏览器在收到响应后,会根据这些字段判断是否允许跨域请求。

要使用CORS,我们需要在JAVA后端设置响应头,例如:

// 设置允许跨域的域名,*表示所有域名
response.setHeader("Access-Control-Allow-Origin", "*");
// 设置允许跨域的方法,如GET, POST, PUT, DELETE等
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
// 设置允许跨域的请求头,如Content-Type, Authorization等
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");

这样,浏览器就可以正常发送跨域请求了。

2.2  方法二:JSONP

JSONP(JSON with Padding)是一种利用<script>标签的特性来实现跨域请求的方法。它的原理是,浏览器可以通过<script>标签加载任何域名的脚本文件,而脚本文件中可以包含JSON格式的数据,并通过一个回调函数来处理。服务器端需要根据请求参数中指定的回调函数名来返回数据。

要使用JSONP,我们需要在前端发送一个带有回调函数名的参数,例如:

// 前端发送一个带有callback参数的请求
<script src="http://www.b.com/data?callback=handleData"></script>

然后,在后端返回一个包含回调函数调用的脚本,例如:

// 后端返回一个包含回调函数调用的脚本
handleData({"name":"Alice","age":18});

这样,浏览器就会执行handleData函数,并传入JSON数据作为参数。

2.3  方法三:代理

代理是一种通过中间服务器来转发跨域请求的方法。它的原理是,浏览器向同源的代理服务器发送请求,代理服务器再向目标服务器发送请求,并将响应返回给浏览器。这样,浏览器就不会直接与目标服务器进行通信,而是通过代理服务器来绕过同源策略。

要使用代理,我们需要在JAVA后端搭建一个代理服务器,并将前端的请求转发给目标服务器,例如:

// 创建一个URL对象,表示目标服务器的地址
URL url = new URL("http://www.b.com/data");
// 打开一个连接对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置连接属性
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.setDoOutput(true);
// 获取输入流和输出流
InputStream in = conn.getInputStream();
OutputStream out = response.getOutputStream();
// 将输入流中的数据复制到输出流中
byte[] buffer = new byte[1024];
int len = 0;
while ((len = in.read(buffer)) != -1) {
    out.write(buffer, 0, len);
}
// 关闭流和连接
in.close();
out.close();
conn.disconnect();

这样,前端就可以通过代理服务器来获取目标服务器的数据了。

 

3. 三种方案 对比

 

方案优点缺点适用场景
JSONP 兼容性好,支持低版本浏览器 只支持GET请求,需要服务器端配合,不能自定义请求头和响应头,安全性较低 只需要读取数据,不需要修改数据,且对安全性要求不高的情况
CORS 支持各种类型的HTTP请求,可以自定义请求头和响应头,安全性较高 需要服务器端开启CORS支持,且不支持低版本浏览器 需要读写数据,且对安全性要求较高的情况
代理 可以绕过浏览器的同源策略,不需要修改服务器端的配置,可以支持任何类型的HTTP请求 需要额外搭建一个代理服务器,增加了网络开销和维护成本 无法修改服务器端配置,或者需要访问第三方服务器的数据的情况

 

4.  总结

本文介绍了三种在JAVA后端实现跨域请求的方法,分别是CORS,JSONP和代理。每种方法都有其优缺点,具体应用时需要根据实际情况选择合适的方法。希望本文对你有所帮助

 

5.  参考资料:

1So, JSONP or CORS? - Stack Overflow 

2浅谈跨域:JSONP 和 CORS - 知乎 

3三种方法解决跨域问题JSONP、CORS、代理转发 - CSDN博客 

4Cors跨域(四):解决方案对决JSONP vs CORS(下) - 阿里 …

1跨源资源共享(CORS) - HTTP | MDN - MDN Web Docs 

2什么是跨域请求及如何实现 - 知乎 

3一文带你了解跨域原理与解决办法 - 知乎 

4什么是跨域请求以及实现跨域的方案 - 简书

posted on 2023-07-03 19:31  白露~  阅读(1301)  评论(0编辑  收藏  举报