我们在进行前后端分离开发中,必不可少的会遇到跨域问题,然而什么是跨域呢?跨域是怎么产生的呢?要怎么解决?
什么是跨域?
跨域是指从一个域名去请求另一个域名的资源,严格来说,只要域名,协议,端口任何一个不同,就视为跨域。
当前页面url | 被请求页面url | 是否跨域 | 原因 |
---|---|---|---|
http://www.xxx.com | http://www.xxx.com/xxxx.html | 否 | 同源(协议、域名、端口号相同) |
http://www.xxx.com | https://www.xxx.com | 是 | 协议不同(http/https) |
http://www.xxx.com | http://www.baidu.com | 是 | 主域名不同(xxx/baidu) |
http://www.xxx.com | http://blog.xxx.com | 是 | 子域名不同(www/blog) |
http://www.xxx.com:8181 | http://www.xxx.com:8080 | 是 | 端口号不同(8080/8181) |
为什么会出现跨域?
出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
怎么解决?
当前运行后端spring boot应用,请求测试数据正常
package cn.demo.demo.controller;
import cn.demo.demo.entities.Score;
import cn.demo.demo.service.ScoreService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
/**
* @author : lwj
* createTime : 2020/2/16 16:00
* description : Reprint please indicate the source
*/
@Controller
@RequestMapping(path = "/score")
public class demoController {
@Autowired
private ScoreService scoreService;
@GetMapping(value = "/findAll")
@ResponseBody
public List<Score> findAll() {
return scoreService.findAll();
}
}
而运行前端Vue应用跨域发送请求后端的数据时,浏览器会报错
request({
url: 'http://localhost:8181/score/findAll',
method: 'get'
}).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
由于端口号不一致,导致跨域的产生
解决方法:
- 加上 @CrossOrigin 注解
import cn.demo.demo.entities.Score;
import cn.demo.demo.service.ScoreService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
/**
* @author : lwj
* createTime : 2020/2/16 16:00
* description : Reprint please indicate the source
*/
@Controller
@CrossOrigin
@RequestMapping(path = "/score")
public class demoController {
@Autowired
private ScoreService scoreService;
@GetMapping(value = "/findAll")
@ResponseBody
public List<Score> findAll() {
return scoreService.findAll();
}
}
这时就可以正常请求到后端的数据了
2. 新建一个配置类
package cn.demo.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author : lwj
* createTime : 2020/2/16 16:30
* description : Reprint please indicate the source
*/
@Configuration
public class CorsConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(false)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedOrigins("*");
}
};
}
}
以上两种方法都可以解决跨域问题
评论区