跨域问题如何解决

跨域问题是由于浏览器的安全策略所导致的。如果在页面中向不同域名或端口号的服务器发送请求,浏览器就会拒绝响应,从而避免恶意网站获取用户的敏感信息。下面是几种解决跨域问题的方法:

  1. 通过在服务器端设置响应头来解决。服务器端需要设置Access-Control-Allow-Origin响应头,可以设置为允许请求的域名或*(表示允许所有域名的请求)。例如,如果你正在使用Node.js作为服务器,可以在响应头中添加以下内容:

package com.example.axiosdemo.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * java中怎么通过在服务器端设置响应头来解决所有请求的跨域问题
 */
@WebFilter(filterName = "corsFilter", urlPatterns = {"/*"})
public class CorsFilter implements Filter {

    @Override
    public void init(FilterConfig config) throws ServletException {
        System.out.println(">>>>>>>>>>>>>>>CorsFilter init");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws ServletException, IOException {
        HttpServletResponse response = (HttpServletResponse) res;

        // 设置允许跨域访问的域名,*为所有
        response.setHeader("Access-Control-Allow-Origin", "*");

        // 设置允许的请求方法
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");

        // 设置允许的请求头
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");

        // 设置响应的缓存时间,单位为秒
        response.setHeader("Cache-Control", "max-age=3600");

        // 放行请求
        chain.doFilter(req, res);
    }

    @Override
    public void destroy() {
        System.out.println(">>>>>>>>>>>>>>>CorsFilter destroy");
    }
}
  1. 使用JSONP(JSON with Padding)来解决。JSONP是一种利用<script>元素的“跨域”技术,它可以通过在URL中添加回调函数的名称来绕过浏览器的同源策略,并在客户端上执行返回的JavaScript代码。例如:

前端代码:

 function handleUserData(data) {
   console.log(data);
   // 处理数据的逻辑...
 }
 
 const userId = 123; // 用户 ID
 const url = `http://localhost:8080/user/${userId}?callback=handleUserData`;
 
 const script = document.createElement('script');
 script.src = url;
 document.body.appendChild(script);

这里的代码中,我们要从跨域的服务端(Spring Boot)获取用户数据。我们先定义了要请求的用户的 ID,然后将它与 API 的 URL 组合起来,同时在 URL 的末尾添加了一个名为 handleUserData 的回调函数参数。

接下来,我们动态地创建一个 <script> 标签,将 URL 设置为上面的 URL,因为我们使用的是 JSONP,所以我们不需要使用 XMLHttpRequest 或 Fetch API 来发起 AJAX 请求,用动态创建的 <script> 标签来发送 GET 请求即可。

最后,在 handleUserData 函数中,我们就可以对返回的数据进行处理了。

服务端代码:

服务端(Spring Boot)需要对接口进行相应的处理,来返回带有回车函数的 JSON 数据。

因为 Spring Boot 使用了 Jackson 库,因此我们可以很方便地实现对 JSONP 的支持。只需在控制器方法上添加 @ResponseBody 注解,并将返回值类型声明为 ResponseEntity<?> 即可。

下面是将用户数据转换为 JSONP 数据的示例代码:

 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
 
 @RestController
 public class UserController {
 
     @GetMapping(value = "/user/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
     @ResponseBody
     public ResponseEntity<String> getUserData(@PathVariable("id") Long userId, String callback) {
         UserData userData = //根据用户ID从数据库中获得用户数据
         String jsonData = new Gson().toJson(userData);
         
         // 将 JSON 数据转为 JSONP 数据
         String jsonpData = String.format("%s(%s)", callback, jsonData);
 
         // 返回 JSONP 数据
         return ResponseEntity.ok(jsonpData);
    }
 
 }

在方法上添加的 produces 设置了返回值是 json 类型的,然后将参数中的 callback 作为回调参数,用 GSON 库将数据转为 JSON 格式,然后将其转换为 JSONP 格式。

最后,实现的效果是前端可以从服务端获取到返回的 JSONP 数据,解析并使用其中的数据。

  1. 使用CORS(跨域资源共享)来解决。CORS是一种使用HTTP头来允许跨域请求的技术,它是浏览器和服务器之间的一种约定。在进行跨域请求时,浏览器会在请求中添加一个Origin头,服务器端在响应中添加Access-Control-Allow-Origin头来告诉浏览器允许跨域请求。例如:

 res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
  1. 使用代理服务器来转发请求。如果无法进行服务器端的设置,可以在客户端上创建一个代理服务器,然后将客户端的请求转发到目标服务器。通过代理服务器,客户端就可以绕过浏览器限制,向不同域名发送请求。

  2.  

 

posted @ 2023-05-16 16:06  jingdy  阅读(246)  评论(0编辑  收藏  举报