Ajax JSON 回调

202 阅读7分钟

重要概念

JSON概念

  • JSON是一门标记语言
  • JSON的本质是字符串!
  • 你别说前端接收到的JSON的本质是string类型数据了,所有由AJAX从服务器端获得的代码都是string类型的数据,一切代码皆为字符串
  • 当我们说JSON字符串的时候,就是JSON格式的文件,也就是JSON这门标记语言

AJAX概念

  • AJAX === async js and xml
  • AJAX诞生的时候本来是为了xml的 甚至有ajaxObject.responseXML这个API方便xml也转换为dom节点,但是两年后就诞生了JSON,于是XML没了市场
  • dom节点有两种类型一种是html一种是xml
  • 最好设置正确的content-type,这是好习惯,虽然你不设置正确的也并不会错
  • ajax对象 === XMLHttpRequest对象 === xhr ,就是:let request = new XMLHttpRequest()
  • http以2开头的都是成功,一般来说ajaxObject.status >= 200 && <300就表示的是请求发送成功
  • 关于响应体的状态码,通常前端只要判断(status>=200 && status<300) 与(status>400) 这两种情况
	- 前者表示success
	- 后者表示fail
	- 状态码3xx通常不会被前端捕捉到
  • 不要去用onload onerror而是用onreadystatechange
  • 区分清楚ajaxObject.readyState(ajax步骤完成到哪一步了), ajaxObject.status(服务器返回的状态码), ajaxObject.onreadystatechange(监听ajax步骤完成到哪一步的函数)
  • 客户端发送请求,请求交给xhr,xhr把请求提交给服务,服务器进行业务处理,服务器响应数据交给xhr对象,xhr对象接收数据,由javascript把数据写到页面上,如下图所示:
  • 专业的前端不会去用 onload 和 onerror,而只是用onreadystatechange

node-dev

修改后可自动为你重启服务器以便快速执行最新代码

平时写的文件,你以为是文件,其实对服务器来说就是提取字符串出来而已

创建ajax一共需要四步骤

open的时候千万不要用后面别的参数 那样不对的 只需要XMLHttpRequstObject.open('GET',URL)

const request=new XMLHttpRequest; // 创建ajaxObject
request.open('GET',path)  // 设置请求的方式和请求的路径
request.onreadystatechange=()=>{ // 为ajaxObeject.onreadystatechange对象 注册回调函数
  if(request.readyState===4&&request.status>=200&&request.status<300){
    const array=JSON.parse(request.response)
    array.forEach(element => {
      let li= document.createElement('li')
      li.textContent=element.id;
      pageUl.appendChild(li)
    });
    console.log(request.response)
    currentPage+=1
  }
}
request.send() // 向后端发送请求

完整解析ajax-demo这个project完整流程

我们只看如何用AJAX实现'请求下一页'功能的 当我们node-dev server.js 8888时,服务器启动了,然后用户在浏览器地址栏中输入localhost:8888/index.html,在server.js中匹配到了逻辑if (path === "/index.html"),然后给xhr设置状态码和响应头,然后去提取文件中的代码形成字符串,然后response.write(string)将string扔回给浏览器 注意,你在浏览器输入localhost:8888/page3.json后之所以能够呈现下图,是因为有业务代码匹配到并成功从一个路径中拿到了你要的文件 如果你只是在文件夹下某个路径放着page3.json,并没有让后端知道应该去哪里拿文件的话,是无法返回你要的结果的

路由是一种路径与返回值之间的对应关系

  • 路径的访问并不单单只有一种方式去键入,以下两种方式对服务器端来说都是路径的访问
    • 最熟悉的是浏览器中用户敲入的路径
    • 也可以是用ajax发请求中的路径

当服务器接收到一个路径时,它会去查看服务器逻辑(代码)是否写过这个遇到这个路径该如何处理?如果这个路径的处理逻辑是要读取一个文件并返回给前端,那么后端就会读取一个文件(其实就是提取该文件形成一串字符串嘛)再扔回给前端。

至于前端是如何处理这个文件的,假如是一段普通的html代码,可以将这段字符串直接append到document的某个node下面,一旦append这段代码给到document,其实就是让浏览器看到了这段代码,也就会自动执行

浏览器能分辨出这段代码是什么代码,比如浏览器知道了你这个是css类型的代码时,才会把这段字符串(其实就是css代码)解析成css的作用

  • 浏览器第一步肯定是要能够读到你的代码(字符串)才有可能执行你的代码
    • 通过你的字符串是否出现在document中以判断我是不是执行这段代码。你没出现我当然无法执行
  • 此外,浏览器第二步还要去检查你代码(字符串)写得是不是对的位置啊
    • 就和你写最基础的HTML一样的,你只有把css代码(css字符串)写在style标签中才有生效的可能性
    • 你只有把js代码(js字符串)写在script标签中才有生效的可能性

readyState的生命周期

mdn-readyState

ajax对象.readyState 出生为0
open 之后 ajax对象.readyState变为1
send 之后 ajax对象.readyState变为2
第一个字节从服务器端返回至浏览器时 ajax对象.readyState变为3
下载完成时 ajax对象.readyState变为4
注意,不管是成功还是失败都会有4

代码书写顺序决定了你是不是能够onreadystatechange顺利检测出1234 不然有可能只检测到234 但这也无关紧要

xhr拿到字符串后在回调函数中处理方法

  • 解析css,创建style标签,把字符串(css代码)塞进style标签中,再把style标签塞到document.head里面
    // 创建style标签
    const style = document.createElement("style");
    // 创建style内容
    style.innerText = request.response;
    // 插入到head里面
    document.head.appendChild(style);
  • 解析JS,创建script标签,把字符串(js代码)塞进script标签中,再把script标签塞到body尾部
    const script = document.createElement("script");
    script.innerText = request.response;
    document.body.appendChild(script);
  • 解析普通的HTML 你直接把返回值放到一个div中,再追加给一个父元素即可正常显示
  • 解析XML 调用xhr.responseXML生成一个XML node,然后可以提取textContent
  • 解析JSON,let obj=JSON.parse(request.response)

JSON

  • JSON数据不一定是对象,也可以是别的数据类型,只不过实际工作中基本都是对象,具体你就看json支持的六种数据类型
  • JSON中的字符串必须是双引号包裹的
  • 如果你要在JSON中写一个对象(key-value pairs),因为key只能是string因此必须用双引号包裹起来
  • 而如果value也是sting则也需要用双引号包裹起来

如何把JSON字符串解析成对象呢?

console控制台中手输JSON字符串需要注意一点

JSON.parse('{"name":"ryan"}');  // 单引号包裹双引号 对js来说合法√ 
// 因为JS不让你双引号里面再写双引号,这在js里是不合法的,但在JSON的规定中key必须是双引号包裹着的,而value如果是string的话也必须是双引号包裹着的
JSON.parse("{"name":"ryan"}"); // 千万不能写成这样 双引号包裹着双引号 对js来说 不合法×
// 类似的
console.log('"这是符合JS规定的"')
console.log(""这是不符合JS规定的"") // 这直接就是一个error了
// 类似的 以下为了表示JSON中的bool类型数据
let string=JSON.parse("true") // 为了表示json这门标记语言中的的bool类型数据,我用双引号的方式去表示这是字符串以便JS能理解这是字符串 是合法的
let string=JSON.parse('true') // 我用单引号去表示字符串以便JS能理解这是字符串 也是合法的
  • 因为JS中 单引号也可以表示字符串 双引号也可以表示字符串 不管你单引号双引号输入,最终都将被JS转成双引号罢了
  • 但是JS不允许你双引号里面包双引号,这是语法错误!

但实际工作中遇不到,因为要么是写在.json文件中的,谁会要你外面再多加一层双引号呢?要么就是

let obj={name:'ryan',age:18};
let string=JSON.stringify(obj);
console.log(string)

回调callback

正确的理解点击事件是一个回调函数,赋给了.onclick这个对象