跨域问题Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin

23 篇文章 0 订阅
15 篇文章 0 订阅

1.bug详情:

vue项目,用axios请求,前后端联调,在局域网内,
浏览器访问别人的地址可以获取数据,但是通过接口请求,就会跨域

2.解决方案【前后端解决方案】:

2.1.前端方案:
2.1.1. 设置Access-Control-Allow-Origin
如果XMLHttpRequest 请求的URL和当前页面不同一个域中时,
浏览器会检测响应http header中有没有 Access-Control-Allow-Origin项,
如果此项值为空或者与当前页面的域不匹配时,就会报此错误。
解决方案:设置Access-Control-Allow-Origin为【请求的域名+端口】,有人也说设置*,情况不同吧,可以试试
config.headers["Access-Control-Allow-Origin"]="http://127.0.0.1:8080";
还有很多其他实现方式,例如:
config.headers.setItem("Access-Control-Allow-Origin","127.0.0.1:8081");
 所以自由发挥,最后头信息加上Access-Control-Allow-Origin就OK
2.1.2. 设置proxyTable
设置proxyTable,实际上就是设置代理路径
(PS:设置config文件之后,需要重新npm run dev)
dev: {
    env: require('./dev.env'),
    port: 8080,
    autoOpenBrowser: true,
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {
         '/api': {
              target: '请求地址ip加端口',
              changeOrigin: true,
              pathRewrite: {
                '^/api': '/' 
              }
            }
    },
  }
2.2.后端方案:
2.2.1. 在controller对应的方法里添加“Access-Control-Allow-Origin”标头”
既然说了《请求的资源上不存在“Access-Control-Allow-Origin”标头》,
那么我就在controller文件对应的方法里给他添加一个标头就好了
/**
  * 查询当前登录用户的信息
  *     DSY
  */
 @RequestMapping(value = "/login", method = RequestMethod.GET)
 @ResponseBody
 public User login(HttpServletResponse response, @RequestParam(value="username")String username,@RequestParam(value="password")String password) {
     response.setHeader("Access-Control-Allow-Origin", "*");
 	return loginService.getUser(username, password);
 }

2.2.2. @CrossOrigin注解解决跨域
如果你用的也是spring框架,并且版本在4.2以上,可以用@CrossOrigin这个注解,
括号中的url可以换成“”*“”,如果这个controller里有多个方法,注解可以直接写在类的最上边。

a.写在方法上:

/**
   * 查询当前登录用户的信息
   *	DSY
   */
  //写在方法上
  @CrossOrigin(origins = "http://localhost:8080/") // 实现跨域  要求spring的版本必须4.2以上
  @RequestMapping(value = "/login", method = RequestMethod.GET)
  @ResponseBody
  public User login(HttpServletResponse response, @RequestParam(value="username")String username,@RequestParam(value="password")String password) {
  	return loginService.getUser(username, password);
  }

b.写在类上:

//写在类上,不用每个方法都写这个注解了
@CrossOrigin(origins="*",maxAge=3600)
@RestController
public class LoginController {}
2.2.3. 今天发现一个特别强的,只需要启动类上加代码就可以了
@Bean
public CorsFilter corsFilter() {
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    final CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true); // 允许cookies跨域
    config.addAllowedOrigin("*");// 允许向该服务器提交请求的URI,*表示全部允许。。这里尽量限制来源域,比如http://xxxx:8080 ,以降低安全风险。。
    config.addAllowedHeader("*");// 允许访问的头信息,*表示全部
    config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
    config.addAllowedMethod("*");// 允许提交请求的方法,*表示全部允许,也可以单独设置GET、PUT等
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}

3.结语:

解决办法还有很多,我提及部分只是对我的项目比较受用,大家可以多尝试尝试,
然后如果单使用哪一条无效就把这些都加上吧,总有一条适合你!!!(我就这么干的໒( ◔ ▽ ◔ ))
以后我遇到新的解决办法也会在博客里更新的。
  • 23
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
跨域问题是由于浏览器的同源策略导致的,同源策略要求网页只能访问与其来源相同的资源。当一个网页向不同源的服务器发送请求时,浏览器会进行跨域检查,如果服务器没有正确配置跨域访问的响应头,就会出现"Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource"的错误。 解决这个问题的方法有多种,下面是两种常见的解决方案: 1. 在服务器端配置响应头信息,允许跨域访问。在服务器端的响应头中添加"Access-Control-Allow-Origin"字段,并设置为允许访问的域名或"*"(表示允许任意域名访问)。 示例代码如下(以Node.js为例): ```javascript // 设置允许跨域访问的响应头 res.setHeader('Access-Control-Allow-Origin', '*'); ``` 2. 使用代理服务器进行请求转发。在项目中配置一个代理服务器,将跨域请求转发到目标服务器,这样就可以绕过浏览器的同源策略限制。 示例代码如下(以Vue.js为例): ```javascript // vue.config.js module.exports = { devServer: { proxy: { '/api': { target: 'http://example.com', // 目标服务器地址 changeOrigin: true, // 允许跨域 pathRewrite: { '^/api': '' // 将请求路径中的/api前缀去掉 } } } } }; ``` 这样,当你在前端代码中发送请求到"/api"路径时,代理服务器会将请求转发到目标服务器,并将响应返回给前端,从而解决跨域问题

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值