跨域(CORS)问题分析与解决方案

1 篇文章 0 订阅
1 篇文章 0 订阅

跨域(CORS)问题分析与解决方案

在这里插入图片描述

复现场景

新创建一个 VUE 工程,使用 fetch 函数(如下所示) 调用后台 GET 接口,希望能够在后台获得到响应。

js code:
fetch('http://127.0.0.1:8080/api/amber/userinfo/hello')
  .then(response => response)

当浏览器访问:http://127.0.0.1:8181/#/ 就出现了问题:后台能够接到请求,但返回响应被浏览器拦截。
查看浏览器的 NETWORK 中显示:

  • Status code : 200
  • Response 没有返回正确结果
  • Console 报错:提示如下 :
Access to fetch at 'http://127.0.0.1:8080/api/amber/userinfo/hello' from origin 'http://127.0.0.1:8081' has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

看报错信息,显然,遇到了跨域问题。根据浏览器策略,所以将请求拦截。
浏览器通过 URL 是否同源 判别我是否做了跨域的操作。

origin(源)

Origin 和 Site 中:

在 Web 中,origin(源)是指 协议(scheme)+ 主机名(host)+ 端口号(port)。

同源(Same origin),意味着 scheme/host/port 三元组完全相同。任意一部分不同,即为跨源(cross-origin,或称为跨域)。

前台地址:http://127.0.0.1:8181/#/ ,后台地址:http://127.0.0.1:8080/api/amber/userinfo/hello
其中 端口号(port) 不同,协议(scheme)和 主机名(host) 一致,可见不同源,且进行了跨源操作。

CORS

Cross-Origin Resource Sharing(CORS),跨源资源共享 或 跨域资源共享,是一种基于 HTTP Header 的机制,用来使服务端指定哪些其他的源可以从这个服务端加载资源。

CORS 在规范区分了预检请求、简单请求。了解 CORS 的工作原理,可以阅读 CORS
或参阅 规范 以获取更多详细信息。

为了允许跨域请求,需要添加 CORS 相关的 HTTP Header。如果在请求的响应中未匹配到 CORS 的 Header,浏览器会拒绝它们。

CORS 解决方案

有时可能只有某一个或者部分接口允许跨域访问,也可能所有接口都需要允许。

根据作用域不同,分为局部解决方案和全局解决方案。

一、局部设置 CORS

方法 1、响应上设置 CORS Header

在请求的响应头上设置:Access-Control-Allow-Origin: *

@GetMapping("/hello")
@ResponseStatus(HttpStatus.OK)
public String getUser(HttpServletResponse response){
   response.setHeader("Access-Control-Allow-Origin", "*");
   return "hello, amber!";
}
方法 2、fetch 时关闭 CORS

在 fetch 请求上增加:mode: 'no-cors' 参数。

fetch('http://127.0.0.1:8080/api/amber/userinfo/hello', {mode: 'no-cors'})
  .then(response => response)
方法3、@CrossOrigin

Spring 从 4.2 版本后开始支持 @CrossOrigin 注解实现跨域,
这在一定程度上简化了我们实现跨域访问的开发成本,
在需要跨域访问的 方法 或者 加上该注解便可允许跨域访问。

①、@CrossOrigin 基于方法级别使用,如下所示:

@RestController
@RequestMapping("/api/amber/userinfo")
public class UserInfoController {

    @GetMapping("/hello")
    @CrossOrigin
    @ResponseStatus(HttpStatus.OK)
    public String getUser(){
        return "hello, amber!";
    }
}

②、@CrossOrigin 在类级别也受支持,并由所有方法继承。如下所示:

@CrossOrigin
@RestController
@RequestMapping("/api/amber/userinfo")
public class UserInfoController {

    @GetMapping("/hello")
    @ResponseStatus(HttpStatus.OK)
    public String getUser(){
        return "hello, amber!";
    }
}

二、全局设置 CORS

除了细粒度、基于注解的配置之外,有时可能还需要全局 CORS 配置。

1、自定义 Filter/HandlerInterceptor
@WebFilter(filterName = "corsFilter", urlPatterns = {"/*"})
@Component
public class CORSConfig implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        res.setHeader("Access-Control-Allow-Credentials", String.valueOf(true));
        res.setHeader("Access-Control-Allow-Headers", "Content-Type,Access-Token,Authorization,ybg");
        res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        res.setHeader("Access-Control-Allow-Origin", "*");
        res.setHeader("Access-Control-Max-Age", "3600");
        chain.doFilter(request, response);
    }
}
2、CorsFilter

Spring 4.2 版本后内置了一个 CorsFilter 专门用于处理 CORS 请求问题,所在包的位置:org.springframework.web.filter.CorsFilter

通过配置 CorsFilter 可实现基于 URL 级别控制跨域访问的范围。

CorsConfiguration config = new CorsConfiguration();

// Possibly...
// config.applyPermitDefaultValues()

config.setAllowCredentials(true);
config.addAllowedOrigin("https://domain1.com");
config.addAllowedHeader("*");
config.addAllowedMethod("*");

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);

CorsFilter filter = new CorsFilter(source);

参考文献

[1]规范: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

[2]@CrossOrigin: https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-cors-controller

[3]CorsFilter: https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-cors-filter

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 uni-app 中,解决请求的方法有以下几种: 1. 使用 jsonp 请求 2. 使用代理,在本地启动一个服务器来作为代理,发起请求时以本地服务器为中介,避免的限制 3. 在服务器端配置,如果服务器端允许,则可以在服务器端设置 HTTP header,允许访问。例如,在 Express.js 中可以使用 cors 中间件来实现。 如果你想深入了解请求的原理,你可以参考以下资料: - 资源共享 (CORS):https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS - HTTP 访问控制 (CORS):https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS - 请求的简单请求与预检请求:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS/Simple_requests_and_preflight_requests ### 回答2: 在uni-app中请求解决方法有以下几种: 1. 使用uni.request方法发送请求时,在请求header中添加"Access-Control-Allow-Origin"字段,允许指定的名或通配符"*",例如: ``` uni.request({ url: 'http://example.com/api', method: 'GET', header: { "Access-Control-Allow-Origin": "*" }, success: function(res) { console.log(res.data); } }); ``` 2. 在uni-app的开发配置文件manifest.json中,添加"networkTimeout"字段来配置请求的超时时间,例如: ``` "networkTimeout": { "request": 10000, "connectSocket": 10000, "uploadFile": 10000, "downloadFile": 10000 } ``` 3. 使用uni.request方法发送请求时,设置withCredentials为true,开启请求携带cookie功能。但需要注意服务器端也需要设置响应头允许接收cookie,例如: ``` uni.request({ url: 'http://example.com/api', method: 'GET', withCredentials: true, success: function(res) { console.log(res.data); } }); ``` 4. 在uni-app的开发配置文件manifest.json中,添加"filters"字段配置全局过滤器来处理请求,例如: ``` "filters": { "request": { "origin": "*", "x-requested-with": "*", "content-type": "application/json" } } ``` 以上是一些常用的uni-app中处理cors请求的方法,根据具体情况选择适合的解决方案。 ### 回答3: 在UniApp中解决问题可以通过配置服务器设置CORS资源共享)来实现。 首先,在后端服务器上设置CORS。在服务器返回响应时,需要在响应头中添加相关的CORS头信息,允许前端访问该接口。常见的CORS头信息包括:Access-Control-Allow-Origin、Access-Control-Allow-Headers、Access-Control-Allow-Methods等。具体配置方法可以根据后端服务器的不同而有所差异,请根据服务器文档进行设置。 其次,在UniApp中发起请求时,需要在请求头中添加Origin字段表示请求的源地址。同时,UniApp默认会在请求头中自动添加Referer字段来表示访问来源,可根据需要进行调整。 另外,UniApp还提供了特定的API来设置请求的配置,可以通过修改uni.request方法的header参数或通过配置uni.request.defaults.header来添加请求头,以适应不同的CORS设置。 需要注意的是,前端涉及到请求时,在接口上必须进行预检请求(Preflight Request)的检测,包括发送一个OPTIONS请求以校验服务器是否允许当前请求。 总结起来,解决UniApp中的CORS问题,需要在后端服务器进行相关CORS设置,并在UniApp中添加请求头信息,确保请求能够正常访问后端接口。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值