说透ajax、fetch、axios之间的关系

1,038 阅读2分钟

前言背景

之所以要回过头来研究ajax是因为最近在研究视频播放地址隐藏的问题,需要用到blod流,而ajax是可以返回blod流的

ajax的使用

如下是一个原生ajax的请求的代码:

    <script>

        let xhr=new XMLHttpRequest();
        xhr.open("get",
        "http://1253228538.vod2.myqcloud.com/c1b0a541vodbj1253228538/d20a0e69387702302713054187/yabhscWGQE4A.mp4",
        true);//true表示异步处理,false表示同步处理。如果是同步处理的话

        xhr.responseType="blob";
        xhr.onreadystatechange=function(){
         
            if(xhr.readyState===4){
                if(xhr.status===200){
                    console.log("响应的结果是:::>>>>",xhr.response);
                    let url=URL.createObjectURL(xhr.response);//把一个blod流编程一个blod地址从而隐藏掉真实的视频地址
            
                    let video=document.createElement("video");
                    video.setAttribute("src",url);
                    video.setAttribute("controls","controls");
                    video.style.width="1000px";
                    document.getElementsByTagName("body")[0].appendChild(video);
                }
            }
        }

        xhr.send(null);//数据



    </script>


问题一:使用ajax去请求资源时,资源地址是http或者是https有区别吗?

没有区别

问题二:同步和异步的问题

如果用异步去返回blod流的话是可以的。

如果同步去返回blod流的话,会如下的错:

错误代码如下:


xhr.html:17 Uncaught DOMException: Failed to set the 'responseType' property on 'XMLHttpRequest': The response type cannot be changed for synchronous requests made from a document.
    at http://localhost/demo/xhr.html:17:25

截图:

image.png

问题三:跨域的问题

如上代码,我访问的是在腾讯云上的视频地址时,是不会有跨域的问题的,下边的代码和结果说明:


//访问的是腾讯云上的视频地址
  xhr.open("get",   "http://1253228538.vod2.myqcloud.com/c1b0a541vodbj1253228538/d20a0e69387702302713054187/yabhscWGQE4A.mp4",
        true);

如果我访问的是普通的视频地址时,会报错跨域的错误:

例如如下代码就会报跨域的错误:

 xhr.open("get",
        "http://www.zhongyin.net.cn/show/player/video1/zhongyinjt.mp4",
        true);//true表示异步处理,false表示同步处理。如果是同步处理的话

报错结果如下:

image.png

fetch的使用

fetch获取数据流

代码如下:

    <script>

        fetch("https://1253228538.vod2.myqcloud.com/c1b0a541vodbj1253228538/d20a0e69387702302713054187/yabhscWGQE4A.mp4",{
            responseType:"blob"//返回的数据类型
        }).then(res=>{
            return res.blob();
        })
        .then(blob=>{
            console.log("blob",blob);
        })


    </script>

axios的使用

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中

特点:

  • 同样的API,node和浏览器全支持,平台切换无压力
  • 使用Promise管理异步,告别传统callback方式

基础使用

cdn的方式:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

npm的安装方式

npm install axios

使用代码:



跨域

既然是ajax库,就不可避免与跨域扯上关系;XHR2是支持跨域请求的,只不过要满足浏览器端支持CORS,服务器通过Access-Control-Allow-Origin来允许指定的源进行跨域,仅此一种方式。

与XHR2一样,fetch也是支持跨域请求的,只不过其跨域请求做法与XHR2一样,需要客户端与服务端支持;另外,fetch还支持一种跨域,不需要服务器支持的形式,具体可以通过其mode的配置项来说明。

fetch的mode配置项有3个值,如下: 1.same-origin:该模式是不允许跨域的,它需要遵守同源策略,否则浏览器会返回一个error告知不能跨域;其对应的response type为basic。

2.cors: 该模式支持跨域请求,顾名思义它是以CORS的形式跨域;当然该模式也可以同域请求不需要后端额外的CORS支持;其对应的response type为cors。

3.no-cors: 该模式用于跨域请求但是服务器不带CORS响应头,也就是服务端不支持CORS;这也是fetch的特殊跨域请求方式;其对应的response type为opaque