Ajax前端后台数据交互分析

纯粹的前端工程师已经不存在了,做前端开发必须要了解必要的后台、数据库知识,以及与后台的交互设计,其中你需要知道的名词包括 JSON、AJAX、序列化、推送、comet、SSE、WebSocket

JSON

js对象

var person = {
	name:'person',
	age:11
}

key和value间用冒号连接,不同的key-value键值对之间用逗号连接,最后一个value后不加符号。

json对象

var person = {
	'name':'person',
	'age':11
}

json对象与js对象的对象字面量的区别在于属性必须加引号。

var person = {
 'name': 'person',
 'age': 11,
 'school': {
  'name': 'school',
  'address': '北京'
 }
 toJSON:function() {
 	return this.name
 }
}

JSON中对象可以嵌套。每个JSON对象使用{}包含。toJSON函数是对象序列化时调用的虚函数。

json数组

var person = [person0,person1,person2]

JSON数组,每一个元素都是json对象。

json对象操作

person0.name = 'person0'
person0['name'] = 'person0'
person0.newName = 'pppp'

json对象与js对象操作方法相同,也是支持属性的增删查改操作。

json数组操作

persons[2].age = person0.age

json数组与js数组操作方法相同

序列化

将js对象、json对象、json数组转化json字符串。

var personstr = JSON.stringify(persons)
person2str = JSON.stringify(preson2, ['name', 'age'], '--')
personstr = JSON.stringify(preson2, function(key, value) {
 if (key == 'name' || key == 'age') {
  return value
 } else {
  return undefined
 }
}, 4)

JSON.stringify将对象(js的或JSON的)转化为JSON字符串(称为序列化)。可以序列化对象或对象数组。会自动滤出值为underfined的属性。

JSON.stringify函数第二个参数是过滤器,表示只保留name和age两个属性,也可以以函数作为过滤器。第三个参数是换行缩进,可为数字缩进空格数目,最大缩进为10,可为字符串,表示缩进字符串。

调用stringify,执行顺序:toJSON虚函数或对象本身->函数过滤器->存在属性进行序列化->缩进参数进行格式化。

反序列化

将json字符串转化为json对象、json数组。

var persons = JSON.parse(personstr)
person2 = JSON.parse(preson2str, function(key, value) {
 if (key == 'name') {
  return 'family' + value
 } else {
  return value
 }
})

JSON.parse将字符串转化为js对象或数组,可以使用函数控制转化操作。

AJAX

Ajax的核心是XmlHttpRequest。我们通过对该对象的操作来进行异步的数据请求。

jQuey中使用.ajax,.post等,Angular中使用$http。

创建XHR对象

var xhr = new XMLHttpRequest();

状态变化事件

xhr.onreadystatechange = function() {
 console.log('readystate=' + xhr.readyState.toString())
 if (xhr.readyState == 3) {
  console.log(xhr.responseText)
 }
}

onreadystatechange()状态变化函数。readyState的取值0为未初始化,未调用open,1已open未send,2已send未回复,3回复部分,4全部回复。在后台使用推送机制的话,前端会间断的收到推送数据,状态为3。responseText包含曾经的所有推送数据,所以每次读取应该根据旧数据长度查找最新的数据的位置。

响应完成事件

xhr.onload = function () {
	console.log('接收响应完成')
}

无论什么响应,接收完成就触发。

响应异常事件

xhr.onerror = function () {
	console.log('响应出错')
}

进度事件

xhr.onprogress = function (event) {
	if (event.lengthComputable) {
		console.log('进度'+event.position*1.0/event.totalSize)
	}
}

lengthComputable表示进度信息是否可用,position表示已接收数,totalSize表示预期接收数。

请求初始化

xhr.open('get','example.php?qunid=12',false)

open()准备启动请求,参数:请求类型post或get,请求地址,是否异步发送。同步的话会等待程序返回方可继续。

发送请求

xhr.send(null)

发送请求,如果是同步,会直到响应完毕才会继续运行。

参数:请求主体。xhr.abort()取消异步请求。

获取响应

if ((xhr.status > 200 && xhr.status < 300) || xhr.status == 304) {
	console.log(xhr.responseText);
	console.log(xhr.getResponseHeader('myback'))
	console.log(xhr.getAllResponseHeaders())
}else {
	console.log('失败:' + xhr.status)
}

responseText返回数据,responseXML在响应类型为text/xml和application/xml时返回XML的响应数据。getResponseHeader读取服务器返回在自定义头部信息。statusText表示HTTP状态描述,各浏览器不同。

超时函数

xhr.ontimeout = function () {
	console.log('响应超时')
}

请求数据序列化

var data = new FormData(myform)
data.append('qunid','21')
data.append('file1',files[0])


xhr.open('post','example.php',true)
xhr.send(data)

FormData对象序列化表单,也可以通过new FormData(),创建空的对象。append添加键值对,可以在包含file的表单中直接添加文件。

comet

Ajax的出现使客户端与服务器端传输数据少了很多,但还是基于http协议,无法摆脱http协议要求的请求/响应的模式。

对于某些需要及时更新的推送通知业务,人们便提出了“反向Ajax”。

Comet的实现主要有两种方式,

基于Ajax的长轮询(long-polling)方式和基于 Iframe 及 htmlfile 的流(http streaming)方式。

而这些大部分功能在后台完成,前端要做的就是通过ajax请求成功后,在XMLHttpRequest的onreadystatechange函数中持续获取数据。

var xhr = getXmlHttpRequest();
xhr.onreadystatechange = function () {
	console.log(xhr.readyState)
	if (xhr.readyState === 3 && xhr.status === 200) {
		//获取成功后执行操作

		//数据在xhr.responseText
		console.log(xhr.responseText)
	}
}

SSE

SSE是一种允许服务端向客户端推送新数据的HTML5技术。与由客户端每隔几秒从服务端轮询拉取新数据相比,这是一种更优的解决方案。

var source = new EventSource('myevent.php')
source.onmessage = function (event) {
	console.log(event.data)
}

source.onerror = function () {
	console.log('连接失败')
	console.log('链接状态'+source.readyState)
}

EventSource对象参数为入口点,必须与创建对象的页面同源(url模式,域、端口)。连接断开会自动建立,或者使用source.close()强制断开。

open事件在连接建立时触发,message事件在接收到新数据时触发,error事件在无法建立连接时触发。推送数据保存在event.data中。

WebSocket

Websocket是一个全新的、独立的协议,基于TCP协议,与http协议兼容、却不会融入http协议。

他被设计出来的目的就是要取代轮询和 Comet 技术

var socket = new WebSocket('ws://www.example.com/server.php')
socket.send('hello world')
socket.onmessage = function (event) {
	console.log(event.data)
	console.log(socket.readyState)
}

总结

AJAX - 请求 ————> 响应 (频繁使用)

Comet - 请求 ————> 挂起 ————> 响应 (模拟服务端推送)

Server - Sent Events - 客户端 <———— 服务端 (服务端推送)

WebSockets - 客户端 <————> 服务端 (未来趋势,双工通信)

 

1.前端请求数据URL由谁来写?
在开发中,URL主要是由后台来写的,写好了给前端开发者.如果后台在查询数据,需要借助查询条件才能查询到前端需要的数据时,这时后台会要求前端提供相关的查询参数,这里的查询参数也就是URL请求的参数。

2.接口文档主要由谁来写?
接口文档也是主要由后台开发者来写的,因为直接跟数据打交道的就是后台,后台是最清楚,数据库里面有什么数据,能返回什么数据.前端开发只是数据的被动接受者.所以接口文档也主要是由后台来完成的,前端只是接口文档的使用者,使用过程中,发现返回的数据不对,则需要跟后台进行商量,由后台来修改.切记 前端不要随意更改接口文档,除非在取得后台开发人员的同意的情况下.总的来讲,接口文档主要由后台来设计,修改,前端开发者起到了辅助的作用。

3.前端开发与后台交互的数据格式主要是什么?
主要是JSON
XML现在用的不多

4.前端开发的后台交互原理?
在项目的时候,我们前后端会大概说一下接口地址,前端请求的参数,后端返回的参数,然后大家就开始写,写的差不多的时候,大家调一下接口看一下返回的数据,没问题就可以了。

5.前端请求参数的形式
GET 和 POST两种方式
对安全性不高 采用get方便
post 要比 get安全
GET - 从指定的服务器中获取数据
POST - 提交数据给指定的服务器处理

6.前端应该告知后台哪些有效信息,后台才能返回前端想的数据的呢?
先将要展示的页面内容进行模块划分,将模块的内容提取出来,以及方便前端的一些标志值等,将所有想要的内容和逻辑告知后端,
后端就会去数据库里面去查找相应的数据表中去获得相应的内容,或者图片地址信息。
URL中的参数主要是根据后台需要,
如果后台需要一个参数作为查询的辅助条件 前端在URL数据请求时就传递参数。
参数前面?
几个参数中间&

7.我们应该怎么把页面这些信息有效传达给后台,以及后台是如何获取到这些数据?
总的来讲:所有前端请求的URL后面的参数,都是辅助后台数据查询的.如果不需要参数,那么后台就会直接给个URL给前端。

8.前端应该如何回拒一些本不属于自己做的一些功能需求或任务?
在与后台打交道中,我们经常遇到这种情况,有时候明明后台来处理某个事件很简单,后台非要你来做,这时候我们应该懂得去回绝他。
原则:前端就是负责把数据展示在页面上
发挥:这就需要我们对一个需求,一个任务的要有清晰认识了,如果对任务含糊不清,自己都没搞明白,你只能受后台摆布了.最后也会因为任务没有完成而备受责难了。

9.当前端在调用数据接口时,发现有些数据不是我们想要的,那么前端应该怎么办呢或者怎么跟后台讲呢?
首先要把请求的URL和返回的数据以及在页面的展示的情况给跟后台看,这样有理有据,后台开发人员是不会说什么的,否则,后台会很不耐烦的,甚至骂你的可能都有,本身做后台比较难,尤其在查询数据,取数据,封装数据方面都比较难处理。

10.为什么需要在请求的时候传入参数?
因为后台在查询数据库的时候需要条件查询。

DEMO

var data=JSON.stringify({"page": {"pagenow": 1,"pagesize": 20},"file":{"name":"jpg"},"catalogs":[{"id":1},{"id":2}]});
        $.ajax({
            type:"POST",
            url:"//访问的url",
            data:data,
            contentType:"application/json", 
            success:function(data){
                //显示数据
            }
        });

注意:

一、contentType

contentType,可以是 application/x-www-form-urlencoded 这种默认类型的,不过当后台有 struts 等框架的话,会在 action 之前拦截请求,并把request body 里面的值都读出来,导致我们不能再request里面读取到值,只能依赖 struts 的 domain model 
所以,如果有后台用这种机制的话,那就需要更改 contentType:application/json ,这样子strust就不会拦截请求了

二、stringify和parseJSON

这两种方法不能乱用,一不小心的话就会导致后台解析不了数据,正确的用法在上面。 
stringify是将Json转义,parseJSON是将json去除转义并解析成对象 


总结

前端传后台json,应该传字符串过去,不能传Object对象,而且要适当指定contentType

 

你可能感兴趣的:(前端后台数据交互)