1. 跨域处理
1.1 异常现象
1.2 异常原因分析
跨源资源共享的官方定义如下:
跨源资源共享(CORS,Cross Origin Resource Sharing。或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),使得浏览器允许这些源访问加载自己的资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的“预检”请求。在预检中,浏览器发送的头中标示有 HTTP 方法和真实请求中会用到的头。
浏览器为了安全,默认会遵循同源策略。即:请求要去的服务器和当前项目(当前项目就理解成前端项目)所在的服务器必须是同一个源。如果不是,请求就会被拦截。那么什么是同一个源呢?什么不是同一个源呢?相同的源指的是 协议、域和端口号要完全相同,这三个地方有任何一处不一样,就是不同源。接下来看看此示例中的错误信息,如下:
Access to XMLHttpRequest at 'http://localhost:8080/api/v1/employees' from origin 'http://localhost' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
上面的错误信息意思是从一个源(前端项目对应的源)http://localhost 给另一个源(后端服务器对应的源)http://localhost:8080/api/v1/employees 发送请求是不被允许的。【此示例中,浏览器页面所在地址是http://localhost/employee/base,浏览器要发送给服务器的请求是:http://localhost:8080/api/v1/employees】。
浏览器对应的源是(也就是前端项目对应的源):【 http://localhost/employee/base】。而浏览器要发送的请求对应的源是(也就是服务器对应的源):【http://localhost:8080/api/v1/employees】
可以发现,浏览器对应的源(http://localhost) 和 请求对应的源(http://localhost:8080) 是不一样的(少了一个端口号8080)。所以就触发了浏览器的同源策略。即: / 之前的东西,必须完全一样,才叫同源,否则就是不同源,如果不同源,默认情况下,浏览器会阻止这样的请求,俗称 "出现跨域问题了"。
同源策略限制浏览器发出的 Ajax、js、css、图片等请求,而不会限制在浏览器地址栏直接发送的请求。这是为什么呢?比如我直接在浏览器地址栏里面输入 http://localhost:8080/api/v1/employees,然后发起请求为什么不会出现跨域问题呢?其实仔细想一想,出现跨域问题的前提是不同源,而现在直接在地址栏给服务器发送请求,哪里有另一个源和服务器对应的源进行比较呢?没有比较,怎么会触发同源策略呢。所以直接在浏览器地址栏发送请求,不用考虑同源策略问题。
但是通过postman等工具发送 http://localhost:8080/api/v1/employees 这个请求为什么没有跨域问题呢,这是因为postman这种请求工具不遵循浏览器标准,不用考虑同源策略问题。
1.3 解决办法
(1)前端自己解决(以后学习前端知识再讨论);
(2)后端解决:设置允许前端跨域。网上有很多解决方案,比如可以参考这篇文章中的:
Spring Boot 解决跨域问题的 5种方案_springboot跨域-CSDN博客