- JS 是一门语言,JSON 是另一门语言,JSON 这门语言抄袭了 JS这门语言
- AJAX 就是用 JS 发请求
- 响应的第四部分是字符串,可以用 JSON 语法表示一个对象,也可以用 JSON 语法表示一个数组,还可以用 XML 语法,还可以用 HTML 语法,还可以用 CSS 语法,还可以用 JS 语法,还可以用我自创的语法
背景
- AJAX是浏览器上的功能
- 浏览器可以发请求,收响应,那么可以将这个功能暴露给JS吗?
- 于是浏览器在windows上加一个XMLHttpRequest函数
- 用这个构造函数(类)可以构造出一个对象
- JS通过它实现发请求,收响应
- AJAX诞生
- 最先由微软的IE5推出来的
- 后来Firefox和Opera才跟进的
如何发请求?
-
用 form 可以发请求,但是会刷新页面或新开页面
-
- get请求是可以携带参数的,想看response,点击一下view sourse就可以看到
-
- POST请求 是不带参数的请求。第四部分是发送的参数数据
-
-
-
用 a 可以发 get 请求,但是也会刷新页面或新开页面
-
- a标签会在当前页面刷新或者新开页面刷新,不是很好用
-
用 img 可以发 get 请求,但是只能以图片的形式展示
用 link 可以发 get 请求,但是只能以 CSS、favicon 的形式展示
用 script 可以发 get 请求,但是只能以脚本的形式运行
有没有什么方式可以实现
- get、post、put、delete 请求都行
- 想以什么形式展示就以什么形式展示
微软的突破
IE 5 率先在 JS 中引入 ActiveX 对象(API),使得 JS 可以直接发起 HTTP 请求。
随后 Mozilla、 Safari、 Opera 也跟进(抄袭)了,取名 XMLHttpRequest,并被纳入 W3C 规范
XMLHttpRequest就是全局下面的一个全局对象
之前出过一个gmail,用来收发邮件,当邮件被点击的时候就会局部更新展示出来。这个突破是可以在网页上面收发邮件,而不用在软件上面。
整个市场因为ActiveX以及XMLHttpRequest的出现,而发生了很大的变化
AJAX
Jesse James Garrett 将如下技术取名叫做 AJAX(Async Javascript And XML):异步的 JavaScript 和 XML
- 用 XMLHttpRequest 发请求
- 服务器返回 XML 格式的字符串(后来不用XML,用了JSON)
- JS 解析 XML,并更新局部页面
如何使用 XMLHttpRequest
- 我们复习一下前面写的server,server的response总是字符串,我们可以给它一个页面格式的字符串,这样到浏览器中就可以解析成网页了,代码如下
var http = require('http') var fs = require('fs') var url = require('url') var port = process.argv[2] if(!port){ console.log('请指定端口奥好不好?\nnode server.js 8888 这样不会吗?') process.exit(1) } var server = http.createServer(function(request, response){ var parsedUrl = url.parse(request.url, true) var pathWithQuery = request.url var queryString = '' if(pathWithQuery.indexOf('?') >= 0){queryString=pathWithQuery.substring(pathWithQuery.indexOf('?'))} var path = parsedUrl.pathname var query = parsedUrl.query var method = request.method /*********从这里开始看,上面不要看*********/ console.log('方方说:含查询字符串的路径为\n' + pathWithQuery) if(path === '/'){ let string = fs.readFileSync('./index.html') //同步读取网页文件 response.statusCode = 200 response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write(string) // 将网页文件写入到response中返回 response.end() }else{ response.statusCode = 404 response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write('呜呜呜') response.end() } /*********代码结束,下面不要看*********/ }) server.listen(port) console.log('监听 ' + port + ' 成功\n请在空中转体720度然后用电饭煲打开 http://localhost:' + port)
- 服务器返回的不是html,而是符合html语法的字符串;
- HTTP的访问路径都是绝对路径,前面没有点的。这个路径需要与HTTP请求头第一句里面的路径一样,否则会请求失败
-
我们网页中如果有要访问的资源,也要将对应到地址信息放入服务器中,否则会请求失败的。
- 接下来我们看看ajax怎么写。
-
open适用于配置的,不是发请求的。第一个参数是请求方式,第二个参数是请求地址,后面三个参数一般默认,其中第三个参数是是否异步,一定要异步,不然就不是AJAX
- 我们写一个简单的AJAX用于监听按钮点击事件,这里我们不使用link标签加载css,而是用ajax
- 四个步骤
- 创建XMLHttpRequest对象
- 调用对象的open方法
- 监听对象的onload&onerror事件
- --专业前端会改用onreadystatechange事件
- --在事件处理函数中操作具体的文件
- 调用对象的send方法(发送请求)
// 使用ajax请求CSS内容 myButton.addEventListener('click', (e)=>{ let request = new XMLHttpRequest() // 创建一个请求对象 request.open('GET', '/xxxx') // 配置参数 request.onload = () => { console.log('成功了') // 创建 style 标签 const style = document.createElement('style') // 填写style内容 style.innerHTML = request.response // 插到页面中 document.head.appendChild(style) } request.onerror = () => { console.log('失败了') } request.send() // 发送请求 })
- 四个步骤
-
这样点击按钮的时候,可以发送请求,请求的方式可以是get,post,put,delete甚至可以自己写一个请求方法,这样我们就实现了使用 XMLHttpRequest 发请求。
- 我们现在实现以下服务器返回XML(虽然现在不用XML了),我们可以查询xml mime type查询XML请求头中Content-Type需要写成什么样。
image.png -
我们接下来实现的是,让JS阅读这段返回的XML,我们之前创建的请求是有监听事件的
[
-
我们看到里面有一个readyState,这个其实监听的是状态。我们拿到这个readyState之后,发现是1,但是XMLHttpRequest里面的却是4。这是因为这个请求需要时间的,这儿的33ms已经是很长了。一个赋值时间很短的
-
请求的时间太长了,所以一时拿不到状态的,我们可以更改一下代码,让状态跟踪不断进行,这样就发现,可以找到状态了
-
这个readState的意思
- 第三行。响应可能是分次返回的,但是这种分次我们无法获知,假设我们返回的有100M,是不可能一次性返回的。
- 我们上面的响应不是从1直接到4的,而是2和3实在太慢了
- 0,1,2,3,4是依次经过的。我们需要记忆的是4状态,说明请求已经将响应下载完毕了
- 有没有一种办法监控到各个状态呢?onreadystatechange
- 创建req对应的readystate为0
- 使用open对应的是1
- 使用send对应的是2
- 当资源开始下载的时候,状态为3
- 当资源完成下载的时候,状态为4
-
myButton.addEventListener('click', (e)=>{ let request = new XMLHttpRequest() // 创建一个请求对象 request.onreadystatechange = ()=>{ console.log(request.readyState) } request.open('GET', '/xxxx') // 配置参数 request.send() // 发送请求 })
-
浏览器返回的状态码如果是3开头的,一定会发另一个请求,最终会得到一2开头或者以4开头的状态码,一般不管3开头的状态码
myButton.addEventListener('click', (e)=>{ let request = new XMLHttpRequest() // 创建一个请求对象 request.onreadystatechange = ()=>{ // readyState等于4有两种情况,一种是成功,一种是失败 if(request.readyState === 4){ console.log('请求响应都结束了') if(request.status >=200 && request.status < 300){ console.log('请求成功。') console.log(request.responseText) // 读取响应的第四部分 }else if(request.status >= 400){ console.log('请求失败。') } } } request.open('GET', '/xxxx') // 配置参数 request.send() // 发送请求 })
-
XML是可以当做页面处理的,但是这个做饭已经过时了。每次都要写比较麻烦的过程去获取其中的数据
我们想简单表示一些有结构的数据。有一个人叫道格拉斯发明了一种语言叫做JSON,这是一门新的语言,用于数据交换语言
-
后台是没有办法返回一个对象给前端的,返回的都是字符串,我们将返回的数据使用json格式的字符串返回
-
我们拿到字符串之后,怎么解析这个对应的字符串呢?可以使用window.JSON.parse,将字符串转成JS对象
myButton.addEventListener('click', (e)=>{ let request = new XMLHttpRequest() // 创建一个请求对象 request.open('GET', '/xxxx') // 配置参数 request.onreadystatechange = ()=>{ if(request.readyState === 4){ console.log('请求响应都结束了') if(request.status >=200 && request.status < 300){ console.log('请求成功。') console.log(request.responseText) // 读取响应的第四部分 console.log(typeof request.responseText) // String let string = request.responseText // 把符合JSON语法的字符串转换成JS对应的值 let object = window.JSON.parse(string) console.log(typeof object) console.log(object.note) console.log(object.note.from) }else if(request.status >= 400){ console.log('请求失败。') } } } request.send() // 发送请求 })
Ajax奠定了前端的基础
myButton.addEventListener('click', (e)=>{
let request = new XMLHttpRequest()
request.open('get', '/xxx') // 配置request
request.send()
request.onreadystatechange = ()=>{
if(request.readyState === 4){
console.log('请求响应都完毕了')
console.log(request.status)
if(request.status >= 200 && request.status < 300){
console.log('说明请求成功')
console.log(typeof request.responseText)
console.log(request.responseText)
let string = request.responseText
// 把符合 JSON 语法的字符串
// 转换成 JS 对应的值
let object = window.JSON.parse(string)
// JSON.parse 是浏览器提供的
console.log(typeof object)
console.log(object)
console.log('object.note')
console.log(object.note)
}else if(request.status >= 400){
console.log('说明请求失败')
}
}
}
})
// 后端代码
}else if(path==='/xxx'){
response.statusCode = 200
response.setHeader('Content-Type', 'text/json;charset=utf-8')
response.setHeader('Access-Control-Allow-Origin', 'http://frank.com:8001')
response.write(`
{
"note":{
"to": "小谷",
"from": "方方",
"heading": "打招呼",
"content": "hi"
}
}
`)
response.end()
使用ajax发送XML
- XML是一种文档类型,我们认识的DOM对象不止是用于HTML,还可以用于XML
- ajax最初诞生的时候就是为了使用responseXML,这是一个XML
- 后来这门语言被JSON替代
const request = new XMLHttpRequest(); request.open("GET", '/4.xml'); request.onreadystatechange = () => { if(request.readyState === 4 && request.status === 200){ const dom = request.responseXML; const text = dom.getElementsByTagName('warning')[0].textContent console.log(text.trim()) } } request.send()
JSON —— 一门新语言
http://json.org
我们想简单表示一些有结构的数据。有一个人叫道格拉斯发明了一种语言叫做JSON,这是一门新的语言,用于数据交换语言
- JSON没有抄袭functionh和undefined
- JSON中字符串的字符串一定是在双引号里面
- JSON没有变量,无法引用,不能表示复杂的对象,只能表示哈希
-
- JSON(JavaScript Object Notation)是一门独立语言
- JSON不是编程语言,是一种标记语言
- JSON可以表示什么?
- {"name": "hahah", "age": "18"}
- 支持的数据类型
- string-只支持双引号,不支持单引号和无引号
- number-支持科学计数法
- bool-true和false
- null-没有undefined
- object
- array
- 不支持函数,不支持变量(不支持引用)
- 使用ajax加载json
- 使用JSON.parse转成对象,使用json代替ajax
const request = new XMLHttpRequest(); request.open("GET", '/5.json'); request.onreadystatechange = () => { if(request.readyState === 4 && request.status === 200){ const object = json.parse(request.response); myName.textContent = object.name } } request.send()
- window.JSON
- JSON.parse
- 将符合JSON语法的字符串转换成JS对应类型的类型
- JSON字符串=>JS数据
- 由于JSON只有六中类型,所以转成的数据也只有6种
- 如果不符合JSON语法,则直接抛出一个Error对象
- 一半用try catch捕获错误
- JSON.stringify
- 是JSON.parse的逆运算
- JS数据=> JSON字符串
- 由于JS的数据类型比JSON多,所以不一定会转换成功
- 如果失败,就抛出一个Error对象
- JSON.parse
总结
- HTTP是个框,什么都能往里装
- 可以装HTML、CSS、JS、XML......
- 记得设置正确的 Content-Type,这是好习惯
- 只要你知道怎么解析这些内容,就可以使用这些内容
- 解析方法
- 得到CSS之后生成的style标签
- 得到JS之后生成script标签
- 得到HTML之后使用innerHTML和DOM API
- 得到XML之后使用responseXML和DOM API
- 不同类型的数据有不同类型的解析方法
- AJAX可以用于数据分页