java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > springboot跨域访问

springboot跨域访问cros与@CrossOrigin注解详析

作者:笨不拉几的菜鸟

这篇文章主要给大家介绍了关于springboot跨域访问cros与@CrossOrigin注解的相关资料,跨域是指不同域名之间相互访问,它是浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制,需要的朋友可以参考下

一、url

   url(uniform resource locator:统一资源定位符)

   协议://域名:端口号/资源路径/文件名

二、同源的含义

所谓同源,就是指请求的资源url和目前文件来源url的协议域名端口都相同。同源即同域,两者意思相同。

举例:网址:http://www.oneRound.com/dir/page.html ,它的协议是http://,域名是www.oneRound.com ,端口是80(http协议在没有指定端口号时,默认端口号是80)。

将表格中的url与 http://www.oneRound.com/dir/page.html 比较判断是否同源

url是否同源原因
http://www.oneRound.com/dir/page/index.html资源路径和文件名不同,但三要素相同
http://www.round.com/dir/page.html域名不同
https://www.oneRound.com/dir/page.html协议和端口号都不同(http协议的默认端口号为80,https协议的默认端口号为443)
http://www.oneRound.com:8080/dir/page.html端口号不同(端口号不写时,端口号为该协议默认的端口号)

三、浏览器的同源策略

浏览器的同源策略是指:js脚本在未经允许的情况下,不能够访问其他域下的内容,以保证用户信息的安全,防止恶意的网站窃取数据。

同源策略主要限制:

1、一个域下的js脚本不能访问另一个域下面的cookie,localStorage和indexDB

2、一个域下的js脚本不能够操作另一个域下的DOM

3、ajax不能做跨域请求

1、限制cookie 等信息的跨源网页读取,为了防止恶意网站通过js获取用户其他网站的cookie,是为了保护本地用户信息

2、限制dom的操作,因为恶意网站可以通过iframe打开系统界面,如果可以获取DOM就相当于可以获取整个系统界面的信息。

3、限制跨域 ajax 请求,是为了保护被跨域请求的服务器中数据库用户信息,更加准确地说是跨域请求能发出去,服务器端能收到请求并正常返回结果,但是结果被浏览器拦截了

 特殊:script标签,img标签,以及link标签可以链接其他域中的资源, 因为这些标签不能通过相应的结果来进行安全问题的操作。

四、跨域访问  

1、什么是跨域访问

从 A 向 B 发请求,如果他们的url非同源,直接访问就会造成跨域问题。跨域是客户端问题,跨域请求有两种情况:

 ①普通的图片、css文件请求,不报错               

②发送Ajax请求,报错

发起跨域请求 --> 浏览器在请求的header上添加origin字段 --> 请求成功发送到服务器 --> 服务器将数据返回给浏览器 --> 服务器返回的响应头中,没有告诉浏览器哪个域名可以访问这些数据(没有设置 Access-Control-Allow-Origin)--> 浏览器将丢弃数据,抛出错误

2、为什么前后端分离项目会产生跨域问题

前后端分离的应用,前端、后端是2个独立的应用,运行在不同端口。在浏览器看来,是不同的域,由于浏览器同源策略的限制,导致不同源之间的通信。前端页面中的ajax请求后端接口,即跨域访问。

3、跨域过程分析

浏览器对前端页面和后台交互url判断,若同源,则直接发送数据请求;若不同源,则发送跨域请求 ---->

判断跨域请求。非简单请求:浏览器会帮我们自动触发预检请求,用于确认请求内容是否符合服务端的要求,如果符合,在进行正式的请求。简单请求:直接发出正常请求。---->

服务器收到浏览器跨域请求后,根据自身配置返回对应文件头。若未配置允许跨域,即文件头里不包含 Access-Control-Allow-origin 字段,若配置过域名,则返回 Access-Control-Allow-origin + 对应配置规则里的域名的方式。 ---->

浏览器根据接收到的响应头里的 Access-Control-Allow-origin 字段判断,若无该字段,说明不允许跨域,抛出一个错误;若有该字段,对字段内容和当前域名做比对,如果同源,即允许跨域,浏览器接受该响应;若不同源,即该域名不可跨域,浏览器不接受该响应,并抛出一个错误。

cros跨域请求之简单请求、复杂请求

简单请求:

 简单请求的内容:

  请求方法:get、post、head

  HTTP的头信息不超出以下几种:Accept 、Accept-Language、Content-Language、

                                                            Content-Type

  Content-Type的值只有以下三种:text/plain、multipart/form-data、application

  请求中的任意XMLHttpRequestUpload 对象均没有注册任何事件,XMLHttpRequestUpload对象可以使用 XMLHttpRequest.upload 属性访问

  请求中没有使用 ReadableStream 对象

简单请求的部分响应头如下:

1.Access-Control-Allow-Origin(必含)- 不可省略,否则请求按失败处理。该项控制数据的可见范围,如果希望数据对任何人都可见,可以填写"*"。

2.Access-Control-Allow-Credentials(可选) – 该项标志着请求当中是否包含cookies信息。与请求时的withCredentials属性保持一致。

3.Access-Control-Expose-Headers(可选) – 该项确定XmlHttpRequest2对象当中getResponseHeader()方法所能获得的额外信息。通常情况下,getResponseHeader()方法只能获得如下的信息: Cache-Control 、Content-Language、 Content-Type、Expires、 Last-Modified 、Pragma 当你需要访问额外的信息时,就需要在这一项当中填写并以逗号进行分隔。

复杂请求:

 复杂请求的内容:

    先发送一次“预请求”,浏览器会询问服务器,当前所在的网页是否在服务器允许访问的范围内,以及可以使用哪些HTTP请求方式和头信息字段,只有得到肯定的回复,才会进行正式的HTTP请求。预请求以OPTIONS形式发送,当中同样包含Origin,并且还包含了两项CORS特有的内容:

    Access-Control-Request-Method – 该项内容是实际请求的种类,可以是GET、POST之类的简单请求,也可以是PUT、DELETE等等。

    Access-Control-Request-Headers – 该项是一个以逗号分隔的列表,当中是复杂请求所使用的头部。

复杂请求的预请求的响应头如下:

1.Access-Control-Allow-Origin(必含) – 和简单请求一样的,必须包含一个域。

2.Access-Control-Allow-Headers -- 可以返回所有支持的头部。

3.Access-Control-Allow-Credentials(可选) – 和简单请求当中作用相同

4.Access-Control-Allow-Methods(必含) – 这是对预请求当中Access-Control-Request-Method的回复,这一回复将是一个以逗号分隔的列表。尽管客户端或许只请求某一方法,但服务端仍然可以返回所有允许的方法,以便客户端将其缓存。

5.Access-Control-Max-Age(可选) – 以秒为单位的缓存时间。Access-Control-Max-Age这个响应首部表示 preflight request (预检请求)的返回结果(即 Access-Control-Allow-Methods 和Access-Control-Allow-Headers 提供的信息) 能够被缓存的最长时间,单位是秒。


本块内容原文链接:https://blog.csdn.net/qq_36582776/article/details/123670373

五、cros解决跨域访问

注:跨源请求的本质是请求别人的信息,所以能否跨域请求,是由被请求的服务器的设置决定的。 

w3c提出跨域资源共享,CORS机制 。CORS 是 Cross-Origin-Resource-Sharing  的缩写,是一种安全机制,当浏览器检测到发送的请求非同源(即跨域)时,会自动在 http 头部添加一个 origin 字段,解决跨域问题的关键就是在服务端的响应头中设置Access-Control-Allow-Origin,即可完成跨域数据获取。

在后台实现跨域的设置,前台就可以访问了

当浏览器发送一个跨域请求时会在 http 头部自动加上 Origin需要服务端配合设置响应头 Access-Control-Allow-Origin:*|Origin 才可完成跨域

六、springboot web项目使用Cros解决跨域

前端的url:http://localhost:8082

后端的url:http://localhost:8086

1、配置全局跨域访问

 在项目路径下创建config文件夹,在config文件夹下创建CrosConfig类实现WebConfigConfigurer

@Configuration
public class CrosConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") //**匹配的是我们所有后台的路径,代表后台共享了什么资源
                .allowedOrigins("http://localhost:8082") //匹配的前台的服务器地址
                .maxAge(300 * 1000)
                .allowedHeaders("*")
                .allowedMethods("*"); //允许的前台的请求方式
 
    }
}

使用示例:

成功! 

2、@CrossOrigin注解

作用:

在controller上添加@CrossOrigin注解用来开启跨域请求,让其他域的请求可以访问该controller,否则所有其他域的访问会全部被拒绝。

详解:

origin属性:允许可访问的域列表

maxAge:准备响应前的缓存持续的最大时间(以秒为单位)

使用位置:

①类

 ②方法

①@CrossOrigin注解用在类上

整个类的方法都可以被允许的域访问

后端controller

@Controller
@CrossOrigin("http://localhost:8082")
//@RequestMapping("/emp")
public class EmpController {
    @Autowired
    private IEmpService empService;
 
 
    @RequestMapping("/getConformEmp")
    @ResponseBody
    public String getConformEmp(@RequestBody Map<String,String> map) {
        System.out.println(map);
        String name = map.get("name");
        String age = map.get("age");
        return  name + "今年" + age + "岁了!";
    }
}

 前端(以Vue为例)

methods:{
    getInfo(){
      this.$http.post("/getConformEmp",{"name":"小明","age":"19"}).then(res => {
        this.pInfo = res.data
      })
    }
  }

成功!

 ②注解用在方法上

有注解的方法可以被指定的域访问

 跨域访问“/getConformEmp”:成功!

跨域访问“/getConformEmp01”:失败!

总结

到此这篇关于springboot跨域访问cros与@CrossOrigin注解的文章就介绍到这了,更多相关springboot跨域访问内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文