AJAX:Async(异步) JavaScript And XML
简单一句话AJAX就是用JS发送请求和收响应
AJAX是浏览器上的功能
浏览器可以发请求,收响应
浏览器在window上加了一个XMLHttpRequest函数
用这个构造函数(类)可以构造出一个对象,window.XMLHttpRequest是用来创建XMLRequest对象的
JS通过它实现发请求,收响应
准备一个服务器(接受请请求)
使用server.js作为我们的服务器
node server.js 8888启动添
添加
index.html
main.js
style.css
路由
server.js
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('有个傻子发请求过来啦!路径(带查询参数)为:' + pathWithQuery)
if(path ==='/'){
response.statusCode = 200
response.setHeader('Content-Type', 'text/html;charset=utf-8')
response.write(`777`)
response.end()
}else if (path === '/index.html') {
response.statusCode = 200
response.setHeader('Content-Type', 'text/html;charset=utf-8')
let string = fs.readFileSync('public/index.html').toString()//把文件读成一个字符串,把字符串传给write。index.html里面有一个占位符page1
const page1 = fs.readFileSync('DB/page1.json').toString()//获取page1的内容 page1 此时得把它变成字符串
//把string里面的占位符替代成数据库里面拿出来的page1字符串
const array = JSON.parse(page1)
const result = array.map(item=>`<li>${item.id}</li>`).join('')
string = string.replace('{{page1}}',`<ul id="xxx">${result}</ul>`)//后端技术就是在HTML里面做个标记,把数据填充过来
response.write(string)
response.end()
} else if (path === '/main.js') {
response.statusCode = 200
response.setHeader('Content-Type', 'text/javaScrip;charset=utf-8')
response.write(fs.readFileSync('public/main.js'))
response.end()
} else if (path === '/style.css') {
response.statusCode = 200
response.setHeader('Content-Type', 'text/css;charset=utf-8')
response.write(fs.readFileSync('public/style.css'))
response.end()
} else if (path === '/2.js') {
response.statusCode = 200
response.setHeader('Content-Type', 'text/javaScrip;charset=utf-8')
response.write(fs.readFileSync('public/2.js'))
response.end()
} else if (path === '/3.html') {
response.statusCode = 200
response.setHeader('Content-Type', 'text/html;charset=utf-8')
response.write(fs.readFileSync('public/3.html'))
response.end()
} else if (path === '/4.xml') {
response.statusCode = 200
response.setHeader('Content-Type', 'text/xml;charset=utf-8')
response.write(fs.readFileSync('public/4.xml'))
response.end()
} else if (path === '/5.json') {
response.statusCode = 200
response.setHeader('Content-Type', 'text/json;charset=utf-8')
response.write(fs.readFileSync('public/5.json'))
response.end()
} else if (path === '/page2.json') {
response.statusCode = 200
response.setHeader('Content-Type', 'text/json;charset=utf-8')
response.write(fs.readFileSync('db/page2.json'))
response.end()
} else if (path === '/page3.json') {
response.statusCode = 200
response.setHeader('Content-Type', 'text/json;charset=utf-8')
response.write(fs.readFileSync('db/page3.json'))
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)
AJAX 加载CSS
加载CSS
以前我们用<linkrel=stylesheethref="1.css"/>(同时添加路由)
今天请用AJAX加载CSS
四个步骤
- 创建HttpRequest对象(全称是XMLHttpRequest)
const request = new XMLHttpRequest() - 调用对象的 open 方法
request.open(method,url) - 监听对象的 onload & onerror 事件
request.onload = ()=>{
conslole.log('成功')
}
request.onerror = ()=>{
conslole.log('失败')
}
专业前端会改用onreadystatechange事件
在事件处理函数里操作CSS文件内容 - 调用对象的send方法(发送请求)
request.send()
request.response是请求得到的响应也就是请求文件的内容
style.css
h1{
color: aqua;
}
main.js
getCSS.onclick = () => {
const request = new XMLHttpRequest()
request.open('GET', '/style.css');//readyState =1
request.onreadystatechange = () => {
//console.log(request.readyState)//监听一下readyState
//下载完成不知道是成功还是失败 成功一定是2xx
if (request.readyState === 4) { 如果下载完成
//console.log(request.status)//我们可以看到响应的状态码是404 那就说明把404下载完了 不是把成功页面下载完了
if (request.status >= 200 && request.status <= 300) {//http里面 状态码是2开头的都表示成功我们只监听两百
const style = document.createElement('style')//创建style标签
style.innerHTML = request.response//获取响应的内容并填写style内容
document.head.appendChild(style)//插到head里面
} else {
alert('加载CSS失败')
}
}
}
request.send()//readyState =2
};
AJAX 加载JS
以前我们用<script src="2.js"/>(同时要添加2.js的路由)
今天请用AJAX加载JS
四个步骤
- 创建HttpRequest对象
- 调用对象的 open 方法
- 监听对象的 onload & onerror 事件
专业前端会改用onreadystatechange事件
在事件处理函数里操作JS文件内容 - 调用对象的send方法(发送请求)
getJS.onclick = () => {
const request = new XMLHttpRequest()
request.open('GET', '/2.js');
request.onload = () => {
const script = document.createElement('script')//创建scrip标签
script.innerHTML = request.response//填写scrip内容
document.body.appendChild(script)//插到里面
}
request.onerror = () => {
}
request.send()
};
AJAX 加载HTML
加载HTML:假设页面有一块内容是动态展示,就用。
你可以把一个页面拆成各个不同的部分用户点击的时候请求这一部分.
getHTML.onclick = () => {
const request = new XMLHttpRequest()
request.open('GET', '/3.html')
request.onload = () => {//创建一个div只需要把它放到HTML里面就行
const div = document.createElement('div')//创建div 填写DIV 内容 插入到身体里
div.innerHTML = request.response
document.body.appendChild(div)
}
request.onerror = () => { }
request.send()
}
onreadystatechang事件
XMLHttpRequest.onreadystatechange - Web API 接口参考 | MDN (mozilla.org)
如果出现错误,比如在上面的代码中路径写错了 request.open('GET', '/3.htl')。onerror并不能很好的触发,而是得到404,也就是server中最后保底的else ,JS会把错误的内容渲染进去,onerror没有触发。所以我们说专业前端会改用onreadystatechange事件在事件处理函数里操作文件内容。
onreadystatechange:只要readyState属性发生变化就会调用相应的处理函数。这个回调函数会被用户线程所调用。
readyState有五个值
0 代理被创建,但尚未调用open()方法
1open()方法已经被调用
2send()方法已经被调用,并且头部和状态已经可获得
3 下载中 responseText属性已包含部分数据
4 下载操作已完成
一个请求的一生 五个过程每一个过程 用一个readyState表示
- 第一个过程 把请求创建出来 就是第一步 const request = new XMLHttpRequest() 用 0 表示
- 第二个过程 open一下 发射火箭 安装火箭阶段 用1表示
- 第三个过程 send 发请求 用2表示
- 第四个过程 等着 当第一个信息(字节)出现在浏览器 标记为3 表示开始下载
- 第五个过程 下载完了 状态变为4
用readyState来判断是否下载完
然后再用request.status状态码判断是否成功,如果是404那说明我们把404页面下载完了
具体看CSS部分
AJAX 加载XML
XML 是AJAX的X ,因为那个时候Json还没有出生只能用XML传递数据
他有request.response,是XML里面的内容
它还有个属性是request.responseXML,自动把信息变成一个DOM对象
getElementsByTagName获取到的是数组
<?xml version="1.0" encoding="UTF-8"?>
<message>
<warning>
Hello World
</warning>
</message>
getXML.onclick = () => {
const request = new XMLHttpRequest();
request.open('get', '/4.xml');
request.onreadystatechange = () => {
if (request.readyState === 4) {
if (request.status >= 200 && request.status <= 300) {
const dom = request.responseXML
const text = dom.getElementsByTagName('warning')[0].textContent//获取到Hello World
console.log(text.trim())//trim消除空格
} else {
alert('加载XML失败')
}
}
}
request.send()
}
小总结
HTTP是个框,什么都能往里装
可以装HTML、CSS、JS、XML……
记得设置正确的Content-Type,这是好习惯
只要你知道怎么解析这些内容,就可以使用这些内容
解析方法
得到CSS之后生成style标签得到
JS之后生成script标签
得到HTML之后使用innerHTML和DOMAPI
得到XML之后使用responseXML和DOMAPI
不同类型的数据有不同类型的解析办法
AJAX 加载JSON
JavaScript Object Notation(JS对象标记语言)
JSON是一门独立的语言 和HTML CSS XML JS一样
不是编程语言 是标记语言 跟HTML XML markdown 一样 用来展示数据
学习它只需要看看铁轨图即可
JSON官方文档
支持的数据类型
string-只支持双引号,不支持单引号和无引号number-支持科学记数法
bool-true和false
null-没有undefined
object (只能是这六种)
array
就这六种,跟JS的七种数据类型区别开来不支持函数,不支持变量(所以也不支持引用)
JSON
{
"name":"frank",
"age":18,
"xxx":null
}
main.js
getJSON.onclick = () => {
const request = new XMLHttpRequest();
request.open('get', '/5.json')
request.onreadystatechange = () => {
if (request.readyState === 4 && request.status === 200) {
// 全新解析版本 弄一个对象 JSON.parse 就是把符合JSON语法的字符串变成对应的对象或其他东西
console.log(request.response)
const object = JSON.parse(request.response)
myName.textContent = object.name
// console.log(object)
}
}
request.send()//readyState =2
}
点击请求JSON
JSON是一个全局变量
JSON对象有两个方法
- JSON.parse
将符合JSON语法的字符串转换成JS对应类型的数据
JSON字符串=>JS数据
由于JSON只有六种类型,所以转成的数据也只有6种
如果不符合JSON语法,则直接抛出一个Error对象
一般用trycatch捕获错误
let object
tyr{
object = JSON.parse(`{'name':'frank'}`)
}catch(error){
console.log('出错了 详情是')
console.log(error)
object = {'name':'no name'}
}
console.log(object)
- JSON.stringify
是JSON.parse的逆运算
JS数据=>JSON字符串
由于JS的数据类型比JSON多,所以不一定能成功
如果失败,就抛出一个Error对象
AJAX 加载分页
首页在server中最做好了
let n = 1;
getPage.onclick = () => {
const request = new XMLHttpRequest();
request.open('get', `/page${n + 1}.json`)
request.onreadystatechange = () => {
if (request.readyState === 4 && request.status === 200) {
const array = JSON.parse(request.response)//首先把这个JSON变为JS数组 ,对于这个数组,每一项插到它后面
array.forEach(item => {
const li = document.createElement('li');
li.textContent = item.id;
xxx.appendChild(li);
});
n += 1;
}
}
request.send()
}