如何和后端交互
- form表单的提交:点击submit提交,浏览器会默认自动的把input表单中的东西提交到form的action这个地址上。可以使用post方式也可以使用get的方式提交数据。key是input name。value是用户的输入。缺点:提交的时候页面会发生跳转;提交是单向提交,无法直接知道后台的响应。
- ajax:异步的JavaScript和XML,起先ajax是用XML格式的数据进行数据交互的,换句话说,当服务器发送请求,服务器返回的是XML格式的数据,现在一般使用JSON,但是后端可以发送任何格式的数据,包括字符串,JSON,XML等等。
- websocket:是一种在单个TCP连接上进行全双工通信的协议。
什么ajax
ajax是一种技术方案,但并不是一种新技术。它依赖的是现有的CSS/HTML/JavaScript,而其中最核心的依赖就是浏览器提供的XMLHttpRequest对象,是这个对象使得浏览器可以发出HTTP请求与接收HTTP响应,实现在页面不刷新的情况下和服务端进行数据交互。浏览器升级之后,出现了fetch,也可以认为是ajax的一种实现。(兼容性差)
- 同步方式获取数据
//get方式:通常用于向服务器查询某些信息
// 1.定义一个对象
var xhr = new XMLHttpRequest()
// 2.设置参数
//false代表同步执行
//调用open()方法并不会真正发送请求,而是启动一个请求以备发送。
//只能向同一个域中使用相同端口和协议的http发送请求。
xhr.open('GET','/nihao.json',false)
// 3. 发送
xhr.send()
// 4.当数据到来后,接受数据并显示
var data = xhr.responseText
console.log(data)
- 异步方式获取数据
//ajax异步执行
var xhr = new XMLHttpRequest()
xhr.open('GET','/nihao.json',true)
//true代表异步的方式执行
xhr.send()
//内部数据到了会默认触发load
xhr.addEventListener('load',function(){
var data = xhr.responseText
console.log(data)
})
- 防止在未正常状态下输出空白
ajax用法改进:
//ajax异步执行
var xhr = new XMLHttpRequest()
xhr.open('GET','/nihao.json',true)
//true代表异步的方式执行
xhr.send()
xhr.addEventListener('load',function(){
if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304){
//执行成功了
var data = xhr.responseText
console.log(data)
}else{
console.log('error')
}
})
- post方式请求数据:用于向服务器发送应该被保存的数据
var xhr = new XMLHttpRequest()
xhr.open('post','/login',true)
xhr.send('userbane=lili&passwoed=123')
//使用URL拼接函数的写法
/* xhr.send(makeURL{
username:'lilili',
age:3
})
*/
xhr.addEventListener('load',function(){
console.log(xhr.status)
//304代表有缓存的状态码
if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304){
var data = xhr.responseText
console.log(data)
}else{
console.log('error')
}
})
- URL拼接的过程
makeURL({
username:'lilili',
age:3
})
function makeURL(obj){
var arr = []
for(var key in obj){
arr.push(key + '=' +obj[key])
}
return arr.join('&')
}
ajax和XMLHttpReuquest()的关系
使用XMLHttpRequest对象来发送一个Ajax请求。
status属性:响应的HTTP状态。
status:200-300表示正常状态码。
status:404表示这个文件不存在。
status:503服务器收到了请求但是内部报错了。
status:304表示这个数据是有缓存的。
readyState,readystateChange:表示请求/响应过程的当前活动阶段。
readyState:存有XMLHttpRequest的状态。从0~4发生变化
0:请求未初始化,尚未调用open()方法
1:服务器连接已建立,启动,已经调用open()方法,但尚未调用send()方法。
2:发送,已经调用send()方法,但尚未接收到响应。
3:请求处理中,已经接收到部分响应数据。
4:请求处理完成且响应就绪。此时,触发load事件。
只要readyState属性的值由一个值变成另一个值,都会触发一次readystatechange事件。必须在调用open()之前指定onreadystatechange事件处理程序才能保证跨浏览器兼容性。与其他事件不同的是,这里没有向readystatechange事件处理程序中传递event对象,必须通过XHR对象本身来确定下一步该怎么做。
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304){
var data = xhr.responseText
console.log(data)
}else{
console.log('error')
}
}
}
xhr.open('GET','/nihao.json',true)
xhr.send()
在接受响应之前,还可以调用abort()方法来取消异步请求,
xhr.abort()
调用这个方法之后,XHR对象会停止触发事件,而且也不在允许访问任何与响应有关的对象属性。
XMLHttpRequest()的介绍
XMLHttpRequest标准又分为Level 1和Level 2。
1.缺点:
- 受同源策略的限制,不能发送跨域请求;
- 不能发送二进制文件(如图片、视频、音频等),只能发送纯文本数据;
- 在发送和获取数据的过程中,无法实时获取进度信息,只能判断是否完成;
- XMLHttpRequest Level 2中新增了以下功能
- 可以发送跨域请求,在服务端允许的情况下;
- 支持发送和接收二进制数据;
- 新增formData对象,支持发送表单数据;
- 发送和获取数据时,可以获取进度信息;
- 可以设置请求的超时时间。
timeout,timeout
此属性可以设置HTTP请求的时限。与之相关的是timeout()事件,用来指定回调函数。
xhr.timeout = 3000
xhr.timeout = function(){
console.log('超过3秒的时间了')
}
timeout属性表示请求在等待多少毫秒之后就终止,再给timeout设置一个数值后,如果在规定的时间内浏览器还没有接收到响应,那么就会触发timeout事件,进而会调用ontimeout事件处理程序。如果在超时终止请求之后再访问status属性,就会导致错误。为避免浏览器报告错误,可以将检查status属性的语句封装在一个try-catch语句中。
FormData对象
ajax直接传送FormData对象与点击submit提交网页表单的效果是一样的。
//定义一个FormData()对象
var formData = new FormData();
//初始化对象,为对象添加append数据
formData.append('username','lilili')
formDta.append('password'',123456)
//发送formData
send(formData)
使用FormData的优点:不必明确地在XHR对象上设置请求头部,XHR能够识别传入的数据类型是FormData的实例,并配置适当的头部信息。
上传文件
假定files是一个"选择文件"的表单元素(input[type="file"]),将它装入FormData对象,之后发送FormData即可实现文件的上传。
var formData = new FormData()
for(var i = 0; i < files.length; i++){
formData.append('files[]', files[i]);
}
send(formData)
level 1:overrideMimeType(),level 2:xhr.responseType()
作用:指定xhr.response的数据类型。
一个获取图片文件的代码示例
// overrideMimeType()
var xhr = new XMLHttpRequest()
//向server端获取一张图片
xhr.open('GET','http://cdn.jirengu.com/book.jirengu.com/img/11.jpg',true)
//将响应数据按照纯文本格式来解析,字符集替换为用户自己定义的字符集
xhr.overrideMimeType('text/plain';charset = x-user-defined)
xhr.onload = function(){
if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304){
//通过 responseText 来获取图片文件对应的二进制字符串
var binStr = this.responseText
//然后自己再想方法将逐个字节还原为二进制数据
for (var i = 0, len = binStr.length; i < len; ++i) {
var c = binStr.charCodeAt(i);
//String.fromCharCode(c & 0xff);
var byte = c & 0xff;
}else{
console.log('error')
}
}
//xhr.responseType()
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
//可以将`xhr.responseType`设置为`"blob"`也可以设置为`" arrayBuffer"`
//xhr.responseType = 'arrayBuffer';
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var blob = this.response;
...
}
};
xhr.send();
xhr.response、xhr.responseText、xhr.responseXML
作用:获取response数据
- xhr.response
- 默认值:空字符串""
- 当请求完成时,此属性才有正确的值
- 请求未完成时,此属性的值可能是""或者 null,具体与 xhr.responseType有关:当responseType为""或"text"时,值为"";responseType为其他值时,值为 null
- xhr.responseText
- 默认值:空字符串""
- 只有当 responseType 为"text"、""时,xhr对象上才有此属性,此时才能调用xhr.responseText,否则抛错
- 只有当请求成功时,才能拿到正确值。
- xhr.responseXML
- 默认值: null
- 只有当 responseType 为"text"、""、"document"时,xhr对象上才有此属性,此时才能调用xhr.responseXML,否则抛错
- 只有当请求成功且返回数据被正确解析时,才能拿到正确值。以下3种情况下值都为null:请求未完成、请求失败、请求成功但返回数据无法被正确解析时
send(data):
作用:表示发送数据。
xhr.send(data)的参数data可以是以下几种类型:
- ArrayBuffer
- Blob
- Document
- DOMString
- FormData
- null
相关事件触发
- onreadystatechange:每当xhr.readyState改变时触发;但xhr.readyState由非0值变为0时不触发。
- onloadstart:调用xhr.send()方法后立即触发,若xhr.send()未被调用则不会触发此事件。
- onprogress:xhr.upload.onprogress在上传阶段(即xhr.send()之后,xhr.readystate=2之前)触发,每50ms触发一次;xhr.onprogress在下载阶段(即xhr.readystate=3时)触发,每50ms触发一次。
- onload:当请求成功完成时触发,此时xhr.readystate=4
- onloadend:当请求结束(包括请求成功和请求失败)时触发
- onabort:当调用xhr.abort()后触发
- ontimeout:xhr.timeout不等于0,由请求开始即onloadstart开始算起,当到达xhr.timeout所设置时间请求还未结束即onloadend,则触发此事件。
- onerror:在请求过程中,若发生Network error则会触发此事件(若发生Network error时,上传还没有结束,则会先触发xhr.upload.onerror,再触发xhr.onerror;若发生Network error时,上传已经结束,则只会触发xhr.onerror)。注意,只有发生了网络层级别的异常才会触发此事件,对于应用层级别的异常,如响应返回的xhr.statusCode是4xx时,并不属于Network error,所以不会触发onerror事件,而是会触发onload事件。
参考文献
阮一峰:XMLHttpRequest Level 2 使用指南
你真的会使用XMLHttpRequest么?
《javascript高级程序设计》
饥人谷前端教程
网友评论