博主自己的工作遇到的问题以及阅读相关的书籍和博客[^1],这里是一个总结。
Ajax的由来
在Ajax之前,超文本传输协议(HTTP)规定Web浏览器如何从Web服务器获取文档和向Web服务器提交表单内容,以及Web服务器如何响应这些请求和提交。
在Ajax之前,使用JavaScript操作HTTP的方式:
- 设置window对象的location属性时候 使用JavaScript设置
- 调用表单对象的submit()方法时候,都会初始化HTTP请求。
window.loaction = 'https://www.bilibili.com';
document.forms[0].submit();
上述两种方式可以通过JavaScript来向服务器传输数据或者跳转页面。
优点: 简单书写
缺点: 会导致Web浏览器重新加载窗口或者窗体的内容(需要加载新的页面才能看到结果)。
那么问题来了,不导致页面重载,不加载新的页面如何提交数据呢?
Ajax就此出现,一种主要使用脚本操作HTTP的Web应用架构,并且不会导致页面重载。
Ajax的使用
Ajax是Asynchronous JavaScript and XML的缩写,其实名字中的XML只是当时的作者考虑意图,不代表现在实际使用。同Ajax一样,Comet也是使用脚本操作HTTP的Web应用架构相关的术语[^2]。一般服务器推送数据或者消息使用Comet,而Ajax是发送或者请求数据到服务器。所以也称为 “Comet推送” ,“Ajax拉取”。
实现Ajax的方式:
- <img>元素的src属性 可以直接加载Web服务器提供的图片。
- <script>标签 可以直接加载Web服务器端提供的js文件。
- <iframe> 标签 使用CSS隐藏,客户端不可见,JavaScript通过遍历<iframe>的文档对象来读取Web服务器提供的数据
前两种方式优点是简单书写操作方便,缺点是只能加载对应格式的文件。img只能加载图片文件,同理script只能加载JavaScript文件。第三种方式需要创建多余的使用标签并且设置CSS进行隐藏标签内容。
script标签的src属性天然支持"跨域"[^3],用来解决跨域,"JSONP"基于此进行发展。注释:JSONP是民间自我开发的,不是官方标准。
在Ajax和Comet之上构建更高级的通信协议是可行的,比如客户端/服务器技术可以用作RPC(Remote Procedure Call远程工程调用)机制 或者 发布/订阅 事件系统的基础。
使用XMLHttpRequest
官方标准: XHR1级 和XHR2级标准(即XMLHttpRequest 1.0和XMLHttpRequest2.0 标准)
XHR1级标准 IE7+都支持, XHR2级标准需要IE10+的支持,所以XHR2级使用需要注意兼容性问题。
具体兼容性可以查看what can i use 网站https://caniuse.com/#search=XHR2
XHR2级和XHR1级区别:
- XHR2级添加了formdata对象 用来操作封装form表单数据
- XHR2级添加了超时以及进度等事件。
- XHR2级添加了跨域的官方处理方式
- XHR1级默认是不跨域的,跨域需要使用民间组织自行发明的JSONP,JSONP不是官方标准。
IE7之前的IE版本中的XMLHttpRequest是非标准的,不顾现在公司都兼容到IE8~9了,所以可以放弃这个非标准的写法了。
1.指定请求
request.open('GET','data.html);
open第一个参数指定HTTP方法或动作,GET和“POST”用的最多一些,"POST"通常用于表单,在请求主体中包含额外数据(表单数据)且这些数据通常存储到服务器上的数据库中。一般情况下,相同的URL的重复POST请求从服务器得到的响应不同(为了防止表单重复提交,后端多采用一些手段阻止这类情况发生,比如token的使用)。
open第二个参数是URL,对于此处只需要关注XHR1级官方默认不跨域就可以,XHR2级官方标准可以跨域。
1.1 设置请求头的问题
request.setRequestHeader('Content-Type',"text/plain");
相同的头调用setRequest()多次,新值不会取代之前指定的值。相反,HTTP请求将包这个头的多个副本或这个头指定多个值。
注意点是:不能自己指定"Content-Length" 、“Date”、“Referer”