JS 重构购物车案例 理解AJAX前后端传输数据的解码编码以及AJAX事件(node做后端)


AJAX简介

首先我们来看w3c给的示例图

在我工作中,用的最多的也是用来传输JSON数据,像官网介绍的这样,Ajax 允许通过与场景后面的 Web 服务器交换数据来异步更新网页。这意味着可以更新网页的部分,而不需要重新加载整个页面,这也是ajax的核心,了解以后那我们来简单的写一个AJAX的步骤

AJAX基本步骤

接下来我们一步步去理解其中的含义

我们先来用node写一个server.js作为我们的后端

server

//加载库中http.js,加载进入赋值给变量http,是一个对象
let http = require('http');
//req就是客户端向服务器端请求的数据
//res就服务器项客户端发送的数据
//http.createServer创建服务
let server = http.createServer(function (req, res) {
	//客户端请求的数据正在接收中的事件
	req.on('data', function (d) {
		console.log(d);
	});
	//客户端请求的数据接收完成的后事件
	req.on('end', function () {
		//写入头部信息,允许传输任意文本信息,并且允许任意域访问
		res.writeHead(200, { 'Content-Type': 'text/plain', 'Access-Control-Allow-Origin': '*' });
		res.write();
		res.end();
	});
});
server.listen(3002, '10.9.170.152', function () {
	console.log('服务开启,开始侦听');
});

 那么基础的步骤写好了,别急,我们一步一步来慢慢完善我们的代码

解码以及编码

我们在发送数据的时候,我们也不知道我们会遇到怎样的后端,那他这个数据到底有没有经过加码呢,同样的,我们将数据发给后端的时候我们要不要经过加码呢,然后后端接受

到我们的数据以后需要先进行解码,所以我们在不知道的情况下,我们默认就是

前端发送之前最后一步时先编码,在发送 前端接收之后第一步先做解码,再做其它内容 例如我们先看看我们发送之前的的数据
     let xhr = new XMLHttpRequest();
        xhr.addEventListener( "load", loadHandler );
        let str = encodeURIComponent( "name=王大锤" );
        xhr.open( "get", "http://192.168.0.103:3002?" + str );
        //    xhr.setRequestHeader("Content-Length","200");

        //        将所有的URI编码格式解码为中文
        console.log( decodeURIComponent( str ) );
        //        将所有的中文转换为URI编码格式
        console.log( encodeURIComponent( str ) );
        xhr.send();
        //        如果长时间没有响应我们需要使用abort来关闭当前的AJAX通信
        //        xhr.abort();
        function loadHandler( e ) {
            console.log( decodeURIComponent( this.response ) );

        }

那我们的打印出来的就是这样的

这种通常用在get发送的时候,

如果是get发送方式,通常在node.js服务中需要写入decodeURIComponent来做解码
let obj = JSON.parse(decodeURIComponent(data));

这里呢还有一个知识点,经常用起来的时候就忘了~~~

在JS中,通过JSON.stringify()方法,可以将JSON对象转化为JSON字符串;通过JSON.parse()方法,可以将JSON字符串转化为JSON对象

发送JSON数据

好了,那么了解了中文的解码以及编码以后,那我们拿到我们之前写的购物车那组数据,那组数据里我们是有中文的,我们尝试用post来发送数据,

我们现在有个需求,后端拿到我们数据以后,把里面的num都加+1,然后再返回给我们

我们在后端接受到以后也要做处理,让我们来看一下我们的server.js

let http = require('http');
let server = http.createServer(function (req, res) {
	let data = '';
	req.on('data', function (d) {
		data += d;
	});
	req.on('end', function () {
		//获取请求头
		let obj = JSON.parse(decodeURIComponent(data));
		obj.map(function (t) {
			t.num++;
		});
		//writeHead()写入请求头
		res.writeHead(200, { 'Content-Type': 'text/html', 'Access-Control-Allow-Origin': '*' });
		//服务器发送数据时,最后发送时编码
		res.write(encodeURIComponent(JSON.stringify(obj)));
		res.end();
	});
});
server.listen(3002, '192.168.0.103', function () {
	console.log('开启服务');
});

 接下来我们开启服务

 那么我们在前端将会收到返回的数据,我们打开看看

 好了,我们的效果已经实现了,综上呢,我们就完成了数据传给后端,后端修改完再传给我们这样的一个过程

AJAX的事件

接下来我们深入研究下ajax当中的readystatechange事件机制以及完整的写法

那我们继续把我们之前的data数据拿过来使用一下

如果我们这样直接执行,会发生什么问题,我们来打开浏览器看一下

可以看到先报了一堆错,然后再去执行,我们可以看一下一共执行了4次,那么这4次过程中,我们有四种不同的情况

我们打印一下xhr看看

 这里显示的4,我们先不管他,因为他是个对象,对象属性会动态改变,我们刷新一下,并且打印一下,console.log(xhr.readyState)看看

 这里代表我们通信道哪一步了,这里看到进行到第一步了

readyState状态

 这里不得不说一下我们的readyState的五个状态

值    状态             描述

0    UNSENT            代理被创建,但是尚未调用open的方法

1    OPENED          open()方法已经被调用

2    HEADERS_RECEIVED    send()方法已经被调用,并且头部和状态已经获得

3    LOADING           下载中,responseText 属性已经包含部分数据 

4    DONE            下载操作完成

这里是五种,不是四种,最早的这种的话,我们的侦听就要放在new之前,基本没什么大用

status状态改变

我们接着打印一下xhr这个对象下面的status看看

 可以看到他代表了我们的状态的改变,在第一步的时候的时候他是0,下载结束以后他的状态改变为200,代表成功

常见的状态码还有常见的404,502等等

那么我们接下来完善我们的ajax

完善AJAX

接着上面的需求,也就回到了我们首文,我们继续改进这个需求,把购物车的数据返回给后端,修改num为2,然后再把数据返回给我们

这时候我们需要在下面调用ajax,所以为了防止代码重复,我们把ajax写入函数,然后调用它

这里也要用到我们的timeout,写在send之前,设定一个时间,如果过了这个时间还没有接收到,那么他就是超时