JavaScript详细解析之网络请求与远程资源

本篇文章给大家带来了关于javascript的相关知识 , 其中主要介绍了关于网络请求与远程资源的相关问题 , 包括了跨源资源共享、预检请求、Fetch API等等内容 , 下面一起来看一下 , 希望对大家有帮助 。

JavaScript详细解析之网络请求与远程资源

文章插图

【相关推荐:javascript视频教程、web前端】
一、Ajax的诞生2005年 , Jesse James Garrett撰写了一篇文章《Ajax - A New Approach to Web Applications》 , 这篇文章中描绘了一个被称为Ajax(Asynchronous JavaScript+XML , 即异步JavaScript+XML)的技术 。 这个技术涉及发送服务器请求额外数据而不刷新页面 , 从而实现更好地用户体验 。 Garrett解释了这个技术怎样改变自Web诞生以来就一直延续的传统单击等待的模式 。
把Ajax推到历史舞台上的关键技术是XMLHttpRequest(XHR)对象 。 在XHR出现之前 , Ajax风格的通信必须通过一些黑科技实现 , 主要是使用隐藏的窗格或内嵌窗格 。 XHR为发送服务器请求和获取相应提供了合理的接口 。 这个接口可以实现异步从服务器获取额外数据 , 意味着用户不用页面刷新也可以获取数据 。 通过XHR对象获取数据后 , 可以使用DOM方法把数据插入网页 。
XHR对象的API被普遍认为比较难用 , 而Fetch API自动诞生以后迅速成为了XHR更现代的替代标准 , Fetch API支持期约promise和服务线程(service worker) , 已经成为及其强大的Web开发工具 。
二、跨源资源共享通过XHR进行Ajax通信的一个主要限制是跨源安全策略 。 默认情况下 , XHR只能访问与发起请求的页面在同一域内的资源 。 这个安全限制可以防止某些恶意行为 。 不过 , 浏览器也需要支持合法跨源访问的能力 。
跨源资源共享(CORS , Cross-Origin Rerource Sharing)定义了浏览器与服务器如何实现跨源通信 。 CORS背后的基本思路就是使用自定义的HTTP头部允许浏览器和服务器相互了解 , 以确定请求或相应应该成功还是失败 。
对于简单的请求 , 比如GET或POST请求 , 没有自定义头部 , 而且请求体是text/plain类型 , 这样的请求在发送时会有一个额外的头部叫Origin 。 Origin头部包含发送请求的页面的源(协议、域名、端口) , 以便服务器确定是否为其提供响应 。
现代浏览器通过XMLHttpRequst对象原生支持CORS , 在尝试访问不同源的资源时 , 这个行为会被自动触发 。 要向不同域的源发送请求 , 可以使用标准XHR对象并给open()方法传入一个绝对URL , 比如:
let xhr = new XMLHttpRequest();xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(xhr.reaponseText); }else{ alert("Request was unsuccessful:"+xhr.status); } }};xhr.open("get","http://www.nezha.con/page/",true);xhr.send(null);跨域XHR对象允许访问status和statusText属性 , 也允许同步请求 , 出于安全考虑 , 跨域XHR对象也施加了一些额外的限制 。
    不能使用setRequestHeader()设置自定义头部;
    不能发送和接收cookie;
    getAllResponseHeaders()方法始终返回空字符串;
因为无论同域还是跨域请求都是用同一个接口 , 所以最好在访问本地资源时使用相对URL , 在访问远程资源时使用绝对URL , 这样可以更明确地区分使用场景 , 同时避免出现访问本地资源时出现头部或cookie信息访问受限的问题 。
三、预检请求CORS通过一种叫预检请求的服务器验证机制 , 允许使用自定义头部、除GET和POST之外的方法 , 以及不同请求体内容类型 。 在要发送涉及上述某种高级选项的请求时 , 会先想服务器发送一个预检请求 。 这个请求使用OPTIONS方法发送并包含如下头部:
    Origin:与简单请求相同;
    Access-Control-Request-Method:请求希望使用的方法;
    Access-Control-Request-Headers:(可选)要使用的逗号分隔的自定义头部列表;
四、Fetch APIFetch API能够执行XMLHttpRequest对象的所有任务 , 但更容易使用 , 接口也更现代化 , 能够在Web工作线程等Web工具中使用 。 XMLHttpRequest可以选择异步 , 而Fetch API则必须是异步 。
fetch()方法是暴露在全局作用域中的 , 包括主页面执行线程、模块和工作线程 。 调用这个方法 , 浏览器就会向给定URL发送请求 。
1、分派请求
fetch()只有一个必需的参数input 。 多数情况下 , 这个参数是获取资源的URL , 这个方法返回一个期约:
let r = fetch('/bar');console.log(r);//Promise<pending>

推荐阅读