fetch与ajax(fetch和ajax的区别,fetch请求携带cookie问题)
相关文档链接
一 、ajax 与 fetch 区别
ajax是用对象来请求数据的 ,而fetch是基于Promise设计的 ,是原生js ,是一个windows全局方法 当接收到一个代表错误的 HTTP 状态码时 ,如404 或 500 ,从fetch()返回的 Promise不会被标记为 reject 。相反 ,它会将 Promise 状态标记为 resolve (如果响应的 HTTP 状态码不在 200 - 299 的范围内 ,则设置 resolve 返回值的ok属性为 false) ,仅当网络故障时或请求被阻止时 ,才会标记为 reject 。 fetch默认不带cookie ,除非你使用了credentials的初始化选项 。(自2018 年 8 月以后 ,默认的 credentials 政策变更为same-origin 。) 所有的IE浏览器都不会支持 fetch()方法fetch没有办法原生监测请求的进度 ,而XMLHttpRequest可以
fetch不支持abort,不支持超时控制 ,使用setTimeout及Promise.reject的实现超时控制并不能阻止请求过程继续在后台运行 ,造成了流量的浪费 。二 、ajax 、fecth与axios
fetch
全局的fetch()方法用于发起获取资源的请求 。它返回一个 promise,这个 promise 会在请求响应后被 resolve ,并传回Response对象 。
当遇到网络错误时 ,fetch()返回的 promise 会被 reject ,并传回TypeError ,虽然这也可能因为权限或其它问题导致 。成功的 fetch() 检查不仅要包括 promise 被 resolve ,还要包括Response.ok属性为 true 。HTTP 404 状态并不被认为是网络错误 。
fetch是低层次的API ,代替XHR ,可以轻松处理各种格式 ,非文本化格式 。可以很容易的被其他技术使用 ,例如Service Workers 。
优势:跨域的处理在配置中 ,添加mode: no-cors就可以跨域了
fetch目前遇到的问题:
fetch只对网络请求报错 ,对400 ,500都当做成功的请求,需要封装去处理 fetch默认不会带cookie ,需要添加配置项。 fetch不支持abort ,不支持超时控制,使用setTimeout及Promise.reject的实现超时控制并不能阻止请求过程继续在后台运行 ,造成了流量的浪费 。 fetch没有办法原生监测请求的进度 ,而XHR可以 。 一个简单的get 、 post请求:ajax
AJAX 是异步的 JavaScript 和 XML 。简单点说 ,就是使用XMLHttpRequest对象与服务器通信 。它可以使用 JSON ,XML ,HTML 和 text 文本等格式发送和接收数据 。AJAX 最吸引人的就是它的“异步 ”特性 ,也就是说它可以在不重新刷新页面的情况下与服务器通信 ,交换数据 ,或更新页面 。
稍微包装一下:
ajax用法详情:
1.open(method, url, async) 方法需要三个参数:
method:发送请求所使用的方法(GET或POST);与POST相比 ,GET更简单也更快,并且在大部分情况下都能用;然而 ,在以下情况中 ,请使用POST请求:
①无法使用缓存文件(更新服务器上的文件或数据库)②向服务器发送大量数据(POST 没有数据量限制)③发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
url:规定服务器端脚本的 URL(该文件可以是任何类型的文件 ,比如 .txt 和 .xml ,或者服务器脚本文件 ,比如 .asp 和 .php (在传回响应之前 ,能够在服务器上执行任务));
async:规定应当对请求进行异步(true)或同步(false)处理;true是在等待服务器响应时执行其他脚本 ,当响应就绪后对响应进行处理;false是等待服务器响应再执行 。
2.send() 方法可将请求送往服务器 。
3.onreadystatechange:存有处理服务器响应的函数 ,每当 readyState 改变时 ,onreadystatechange 函数就会被执行 。
4.readyState:存有服务器响应的状态信息 。
0: 请求未初始化(代理被创建 ,但尚未调用 open() 方法)1: 服务器连接已建立(open方法已经被调用)2: 请求已接收(send方法已经被调用 ,并且头部和状态已经可获得)3: 请求处理中(下载中 ,responseText 属性已经包含部分数据)4: 请求已完成 ,且响应已就绪(下载操作已完成)
5.responseText:获得字符串形式的响应数据 。
6.setRequestHeader():POST传数据时 ,用来添加 HTTP 头,然后send(data) ,注意data格式;GET发送信息时直接加参数到url上就可以 ,比如url?a=a1&b=b1 。
axios
Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中 。它本质也是对原生XMLHttpRequest的封装 ,只不过它是Promise的实现版本 ,符合最新的ES规范 。
Vue2.0之后 ,尤雨溪大大推荐大家使用axios来请求数据。优点:
从浏览器中创建XMLHttpRequests 从node.js创建http请求 支持PromiseAPI 拦截请求和响应 转换请求数据和响应数据 取消请求 自动转换JSON数据 客户端支持防御XSRF缺点:
只持现代代浏览器三 、fetch请求中的跨域和携带Cookies问题
在有些请求中会遇到希望通过请求来访问不同源的api ,并且希望携带cookies 。
解决跨域问题
fetch可以设置不同的模式使得请求有效. 模式可在fetch方法的第二个参数对象中定义.
可以定义的模式如下:
same-origin:表示同源可以进行访问 ,反之浏览器拒绝cors: 表示同源和带有cors响应头的跨域可以请求成功 ,其他拒绝cors-with-forced-preflight: 表示在发出请求前, 将执行preflight检查.no-cors: 表示跨域请求不带cors响应头场景 ,此时的相应类型为opaque ,但是在opaque的返回类型中 ,我们几乎不能查看到任何有价值的信息 ,比如不能查看response, status, url 。
解决跨域携带cookies问题
为了让浏览器发送包含凭据的请求(即使是跨域源) ,要将credentials: include添加到传递给fetch()方法的init对象。
解决fetch没有超时时间
方案一
使用一个promise来封装 ,通过setTimeout()来设置一个时间,如果超过该事件 ,就返回reject 。
在这里 ,fetch会和setTimeout同时执行,因为fetch是异步的 ,不会堵塞后面setTimeout的执行 。
方案二
使用ES6中promise方法:
Promise.race([promise1,promise2]) 传入多个Promise对象 ,等待最快对象完成 Promise.all([promise1,promise2]) 传入多个Promise 对象 ,等待所有对象完成如果需要取消请求 ,可以使用AbortController , 用于手动终止一个或多个DOM请求 ,通过该对象的AbortSignal注入的Fetch的请求中 。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!