跨域知识介绍

什么是跨域?为什么会发生跨域?

  • 当请求的地址与来源地址的协议\域名\端口中的任一值不相同时, 均视为是一个跨域的请求,如果请求的TYPE 是XMLHttpRequest(xhr) 则根据浏览器的同源策略,浏览器请求发送出去会收到正常返回结果,但是浏览器不会解析,因为浏览器禁止了跨域请求解析。
  • 同时w3c 为浏览器制定了可以跨域通信规范Cross-Origin Resource Sharing(CORS)通过使用 XMLHttpRequest 对象, CORS可以让开发者方便的进行跨域通信,通过添加一些特殊的请求\响应头, 就像在使用同域通信一样.

在这里插入图片描述

解决跨域的方法

1.浏览器中关闭跨域检查,就可以解析跨域问题。(放弃)

缺点:

  • 需要每个客户端都关闭跨域,不现实
  • 浏览器默认启用,足以说明安全性,启用会导致一些安全性问题。

缺点很明显,所以就不做过多分析,没人用这种方法

展示:

cmd进入chrome.exe的目录键入以下命令
C:\Users\Lu\AppData\Local\Google\Chrome>chrome --disable-web-security  --user-data-dir

在这里插入图片描述

2.通过JSONP实现跨域请求

如何解决跨域?

  • JSONP是什么?
    HTML 的<script> 元素是一个例外(支持跨域)。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
  • JSONP的原理?
    发送一个jsonp的请求,实际是发送一个请求,并且添加一个collback的参数方法给后台,后台将数据作为 对象内容,将jsonp传过来的collback值作为方法名称返回前段为一个 script 方法,方法名就是collback的值,方法体就是我们请求返回的内容,因为script 没有跨域问题,这里就是script的解析了,解析出我们的数据。

简单说:前段发送地址和script方法名->后台获取方法名,查询数据 包装为script function返回给前短,动态插入使用后删除,浏览器script支持跨域方法调用。

3.JSONP修改方式? 需要修改后端代码

  • 前段请求发送agax请求 添加 dataType: “jsonp” //默认请求自动添加callback参数
  • 后台添加jsonp支持 添加 JsonpAdvice extends AbstractJsonpResponseBodyAdvice
        @ControllerAdvice
        class JsonpAdvice extends AbstractJsonpResponseBodyAdvice{
            public JsonAdvice(){
                super("callback");      //添加前段传来的callback【名字可变,前后保持一致即可】
            }
        }
  • 发送的请求 TYPE 是 script 格式,context-type 是 application/javascript

    在这里插入图片描述

4.弊端

  • jsonp 需要改动服务端,当我们是调用方,改不了 被调用方的服务端。
  • jsonp只支持GET请求,不能满足日常开发
  • 发送的不是XHR请求,不能使用XHR的新特性,不方便

解决XHR的跨域请求(推荐使用)

解决XHR的跨域 的原理?

在这里插入图片描述

浏览器对XHR跨域拦截是先请求还是先判断?

简单请求 【先请求,后判断】

  • 方法为:
    • GET
    • HEAD
    • POST
  • 请求header里面
  • 无自定义头
  • Content-Type为以下几种:
    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded

非简单请求 【先判断后请求】

工作中常见的有:

  • put、delete 方法的ajax请求
  • 发送json格式的ajax请求
  • 带自定义头的ajax请求

非简单请求 会现发送一个 options 的请求,主要是确定服务端是否支持跨域,如果支持,则发送真正请求,如果不支持,将不会发送真正请求。

如何判断?

浏览器查看返回的response中是否有 Origin 标示,如果没有则表示不支持跨域,有则是 W3C 的CORS规范实现跨域。

在这里插入图片描述

被调用方解决跨域

服务端解决 Filter设置 origin参数

  • 编写filter添加两个参数,代码如下:(不满足带coocik的请求)

  • 查看请求返回response header

nginx 解决

server{
    listen 80;
    server_name b.com;
    
    location / {
        proxy_pass http://localhost:8080/;
        
        add_header Access-Control-Allow-Methods *;
        add_header Access-Control-Max-Age 3600;
        add_header Access-Control-Allow-Credentials true;
        
        add_header Access-Control-Allow-Origin $http_origin;
        add_header Access-Control-Allow-Headers $http_access_control_request_headers;
        
        if($request_method = OPTIONS){
            return 200;
        }
        
    }
}

spring配置

@CrossOrigin 注解可以直接 解决 跨域

  • 可以加在在方法上
  • 也可以加在类上
@RestController
@RequestMapping("user")
@CrossOrigin
public class UserController{
    @GetMapping("getUser")
    public ResultBean getUser(){
        return new resultBean;
    }
}

调用方解决

nginx 解决

server{
    listen 80;
    server_name a.com;
    
    location / {
        proxy_pass http://localhost:8081/;
    }
    
    location /ajaxserver{
        proxy_pass http://localhost:8080/test/;
    }
}

相关视频:慕课网 http://www.imooc.com/learn/947

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值