• 跨域解决方案


    因为浏览器可以同时打开很多页面,可以同时保存很多授权信息,浏览器为了安全问题,采用了同源策略(浏览器存在跨域问题,服务器不存在跨域问题)

    同源策略:是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSRF等攻击。同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。

    比如,浏览器的地址是baidu.com,页面通过ajax请求京东,就存在跨域,浏览器就阻止了该行为

    现在有一个需求,两个服务器A和B,浏览器通过请求服务器A获取页面A,然后在页面A下通过ajax请求访问网页B,浏览器是不允许这样操作的,但是可以通过一些条件可以去实现

    1.浏览器的页面A通过Ajax请求访问B页面时,浏览器可以先询问服务器B是否同意

    如果页面A通过ajax直接访问页面B,会报错 cors -> cross origin resources sharing error,MissingAllowOriginHeader(跨域资源共享,丢失了允许跨域的头)

    解决方案:

    1. @RestController
    2. public class UserController {
    3. //方式一:手动添加请求头
    4. @RequestMapping("/user")
    5. public User getUser(HttpServletResponse response){
    6. //第一个参数是添加一个请求头,第二个参数是允许请求的来源地址
    7. response.addHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8081");
    8. //10秒钟之内再次请求的时候,就不用发送预检请求了
    9. response.addHeader("Access-Control-Max-Age", "10");
    10. //允许你发送的请求是GET请求还是POST请求
    11. response.addHeader("Access-Control-Allow-Method", "GET");
    12. return new User("java", "java");
    13. }
    14. //方式二:添加注解@CROSSORIGIN
    15. @RequestMapping("/user")
    16. @CROSSORIGIN(origin = {"http://127.0.0.1:8081"})//添加来源地址
    17. public User getUser(HttpServletResponse response){
    18. return new User("java", "java");
    19. }
    20. }

    浏览器的页面A访问页面B的时候,会发送两个请求,第一个请求是option——预检请求,第二请求是get——获取数据

    2.服务器与服务器之间是不存在跨域问题的,因为浏览器可以同时打开十几个网站,这时,浏览器既有A页面的授权信息,也有B页面的授权信息,而服务器不可能打开十几个网站,并获取到别的页面的授权信息,否则A网站就相当于做了B网站的认证了,浏览器使得客户端能够将多个网站的用户信息都存在同一物理环境,而服务器只能保存自己所提供服务的信息

    解决方案:浏览器通过网页A访问服务器A,服务器A再去访问服务器B,这样服务器A就相当于一个中间代理,去获取服务器B的网页信息

    实现一:可以通过http请求服务器B获取网页B的数据,例如restTemplate,相当于手写一个方向代理服务器

    实现二:nginx(方向代理,动静分离,负载均衡),修改配置文件

    server {
            listen       80;
            server_name  localhost;

            ##添加以下标红的部分

            location /api {
                proxy_pass http://127.0.0.1:8082;    ##路径带有api的请求转发到端口为8082的服务器
            }

            location / {
                root   html;
                index  index.html index.htm;
            }

            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
        }

    正向代理:用户A访问Google,由于存在墙,用户A只能通过先访问香港的服务器,由香港的服务器转发请求到Google服务器,这种代理模式是,用户明确要访问的地址,由于无法直接访问到最终的服务器,只能通过中间服务器去访问,直接输入Google的地址就可以了  

    反向代理:用户B访问代理服务器,但是服务器B要访问哪获取数据,用户不知道

    3.jsonp利用浏览器天然支持跨域的标签

  • <script src="http://127.0.0.1:8082/cross">script>
  • 后端代码

    1. @RequestMapping("/cross")
    2. public String cross(HttpServletResponse response){
    3. return "callback('123')"
    4. }

    请求返回后,返回的字符串会调用前端方法cross,最终打印出123

    当使用script请求地址时,会将返回的字符串,默认当成js解析。由于后端返回是的callback(xxx),所以会调用本地的callback函数。

    从原理上来看,要使用JSONP,必须要后端返回相应的数据,这个就是JSONP的模式了,允许客户端传递一个callback函数,后端将数据包裹在callback函数中返回。

    从原理也能看出,JSONP并不要求必须传递JSON格式的数据,只要是JS函数能够认可的数据都是可以传递的

  • 相关阅读:
    LeetCode每日一练 —— 21. 合并两个有序链表
    (附源码)springboot 智能停车场系统 毕业设计065415
    RSA 非对称加密解密,可以javascript和java加解密
    亚特兰蒂斯--扫描线
    技术分享 | Bug定位方法
    FL Studio All Plugins Edition2024中文完整版Win/Mac
    Skywalking
    详解openGauss客户端工具gsql的高级用法
    mysql中的binlog用法
    如何给async await批量添加try…catch?
  • 原文地址:https://blog.csdn.net/DiligentDog/article/details/127673919