文章目录
Ajax
- 数据传输
- 请求数据
- XMLHttpRequest(XHR)
- 动态脚本注入
- Multipart XHR
- 信标(beacons)
- 数据格式
- XML
- JSON
- HTML
- 自定义格式
Ajax性能指南
- 设置HTTP头信息
- 本地数据存储
- 小节
Ajax全称: Asynchronous Javascript And XML (异步 JavaScript 和 XML)
有关Ajax的博客其实数不胜数了,我之前写过的博客中也存在一些Ajax的内容
不过Ajax也是高性能JavaScript的基础知识,可以通过延迟下载体积较大的资源文件来使得页面加载速度更快。
通过异步方式在客户端和服务端之间传输数据,甚至可以只用一个HTTP请求就获取整个页面的资源 (肯定不是赞成这种方式)
Ajax从最基本层面上: 一种与服务器通信而无须重载页面的方法
五种常用技术用于向服务器请求数据:
当然在目前来说,只有三种比较常用,那就是XHR、动态脚本注入和Multipart XHR
这是目前最常用的技术,允许异步发送和接收数据
MDN介绍
这是Ajax的核心,所有主流浏览器对它都提供了完善的支持,也就是说不支持这个的都是非主流浏览器
使用范例:
let url = '接口名称';
let params = ['id=123', 'name=456'] //请求参数
const req = new XMLHttpRequest();
req.onreadystatechange = function(){
if(req.readyState === 4) {
//判断响应状态是否成功
let responseHeaders = req.getAllResponseHeaders(); //获取响应头信息
let data = req.responseText; //获取响应数据
// 数据处理
}
}
// 这是get方法&des=get方法的参数直接在接口后面追加
req.open('GET',url + '?' + params.join('&'), true);
req.setRequestHeader('X-Requested-with','XMLHttpRequest');//设置请求头信息
req.send();//发送请求
readyState状态值有五种状态 (这和status状态码还是有区别的):
status状态码是XMLHttpRequest对象的一个属性,表示响应的HTTP状态码
举个例子:404,也就是我们常说的和谐之光,实际指的是没有发现文件或者URL没有找到对应页面
区别:
由于XHR提供了高级的控制,所以浏览器增加了一些使用XHR的限制
最出名的限制就是同源策略了,不能使用XHR从外域请求数据
至于低版本的IE不仅不支持“流”,也不会提供readyState为3的状态,从服务器传回的数据会被当作字符串或者XML对象,导致处理大量数据变慢。 不过这一点我认为可以略过了,这里低版本IE指IE6及以下,如果现在做的项目还需要兼容这些浏览器,那真的也没什么可说的了
注意(下面主要是从性能上说):
这种技术最大的好处,就是相较于XHR来说,能够进行跨域请求。
因为这是一个Hack,所以不需要实例化一个对象,可以直接用JavaScript创建一个新的脚本标签,并设置src属性为不同域的URL。
let scriptElement = document.createElement('script');
scriptElement.src = '路径';
document.getElementsByClassName('head')[0].appendChild(scriptElement);
这一点其实大部分人也看到过,前端的跨域解决方案之一
就是可以使用script标签进行跨域
注意:
虽然缺陷比较多,但是这项技术的速度非常快,响应消息是作为JavaScript执行的。
引入外部JavaScript代码时一定要多加小心,这种技术从你无法直接控制的服务器上请求数据时可能会有危险,JavaScript没有任何权限和访问控制的概念,谁知道你引入的到底是什么东西
MXHR允许客户端用一个http请求就从服务器想客户端传送多个资源。
Multipart XHR通过在服务器将资源打包成一个由双方约定的字符串分割的长字符串发送到客户端,然后在客户端解析这个长字符串,根据mime-type类型和传入的其他信息解析出每个资源
这个其实也是基于XHR的变种吧?
这项技术类似于动态脚本注入
使用JavaScript创建一个新的Image对象, 并把src属性设置为服务器上的脚本URL.。该URL包含了我们要通过GET传回的键值对数据。信标无法发送POST请求
请注意并没有创建img元素或把它插入DOM
var url = '接口名称';
var params = [数据]
var beacon = new Image();
beacon.src = url + '?' + params.join('&');
// 用load事件监听服务器是否成功接收数据
// 可以在服务端做出不同的响应,比如返回x宽的空白图片代表成功接收,y宽的空白图片代表接收失败
beacon.onload = function() {
if (this.width == x) {
// 成功
} else if (this.width == y){
// 失败,请重试
}
}
beacon.onerror = function() {
// 出错,稍后重试并创建另一个信标
}
范例:
HTML页面:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> beacons title>
head>
<body>
<button onclick="beaconbtn()"> 信标 button>
<script>
function beaconbtn() {
var url = 'http://localhost:3001/goodsList.png';
var params = ['id=123', 'name=空城机', 'data=测试数据是否能够在后台接收'] //发送的数据
var beacon = new Image();
beacon.src = url + '?' + params.join('&');
// 用load事件监听服务器是否成功接收数据
// 可以在服务端做出不同的响应,比如返回x宽的空白图片代表成功接收,y宽的空白图片代表接收失败
beacon.onload = function() {
console.log(this)
if (this.width == 1) {
// 成功
console.log("服务器获取数据成功")
} else {
// 失败,请重试
console.log("服务器获取数据失败,请重试")
}
}
beacon.onerror = function() {
// 出错,稍后重试并创建另一个信标
}
}
script>
body>
html>
Node.js服务器:
const fs = require('fs');
const path = require('path');
const url = require('url');
const express = require('express');
var app = express();
app.use('/',function(req, res) {
//解析出请求的文件路径
var pathname = url.parse(req.url).pathname;
console.log('接收到请求,请求的是:' + pathname);
console.log('服务器接收:')
console.log(req.query)
fs.readFile(pathname.substr(1), function(err, data) {
if (err) {
console.log(err)
} else {
res.end(data)
}
});
})
//服务器本地主机的数字
app.listen('3001',function(){
console.log("启动了。。。, 运行 http:localhost:3001/beacons.html ")
})
当考虑数据传输技术时,你必须考虑这些因素:功能性、兼容性、性能以及方向(你发送给服务器还是服务器发送给你)
如果考虑数据格式,那唯一需要比较的标准就是速度,没有哪一种数据格式会始终比其他格式更好,但目前JSON最主流
最初Ajax开始流行时,选择的是XML作为数据格式 (PS:那时JSON还没正式作为交换格式)
但是相比其他格式,XML极其冗长,对JavaScript程序员解析时十分费力,不能轻易完成。
最重要的是XML解析起来的性能你远比其他数据格式慢,在高性能Ajax中,XML已经没有立足之地了
所以我建议,不是特别老的项目就不要用这个XML了,让前端轻松一点吧!!!
嗯,这是目前最流行的数据格式,其实也不需要我多说,大部分前后端数据交流应该都会用到
JSON是一种使用JavaScript对象和数组直接来编写的轻量级且易于解析
的数据格式
上面JSON的定义中已经把好处说的明明白白了,JSON是高性能Ajax的基础
小知识:
JavaScript中可以使用eval来解析JSON字符串,但是在代码中使用eval
其实很危险,特别是用于执行可能包含恶意代码的第三方JSON数据。 所以尽可能使用JSON.parse()
来解析
这种数据格式与XML类似,JavaScript可以将较大的数据结构转换为简单的HTML,但是服务器处理更快,服务器可以处理好整个HTML传回客户端。
但是这项技术的缺点也十分明显,数据更加臃肿,在网络中传输速度会变慢
理想的数据格式应该只包含必要结构,可以自己定义一种这样的格式,简单地把数据用分隔符连接起来
Jojo;data;hello world;the;people;new;
这种方式速度最快,可以使用split分割字符串的方式进行。 但这里需要确认的是分割的字符是设定好的,不然可能会分割出错
有两种主要方法可以避免发送不必要的请求:
第一种技术使用最简单而且好维护,第二种技术给你最大的控制权
如果希望Ajax响应能被浏览器缓存,那么必须使用GET方式发送请求
还需要在响应中发送正确的HTTP头部信息
设置Expires是最简单确保浏览器缓存Ajax响应的方式
这种方式就是比较手工了
把从服务器接收到的数据存到本地,比如说cookie、local storage
这里就不多介绍了,可以参考以下文章:
Cookie、Session、AJAX、JSON
浅谈cookie、sessionStorage 和 localStorage
一些准则有利于加速Ajax:
顺便推荐一波别人的讲解 狗头.jpg:教你怎么用ajax来进行交互(入门必看)!!!