用JS发请求和收响应,这就是AJAX的全部内容。
准备一个server.js
server.js
安装node-dev
yarn global add node-dev
使用node-dev
(好处:会自动重启)
node-dev server.js 8888
添加index.html/main.js路由
if(path === '/index.html'){response.statusCode = 200response.setHeader('Content-Type', 'text/html;charset=utf-8')response.write(`<!DOCTYPE html><html><head><title>ajax</title></head><body>AJAX demo<script src="/main.js"></script></body></html>`)response.end()}else if(path === '/main.js'){response.statusCode = 200response.setHeader('Content-Type', 'text/javascript;charset=utf-8')response.write(`console.log("我是JS")`)response.end()}else{response.statusCode = 404response.setHeader('Content-Type', 'text/html;charset=utf-8')response.write(`你输入的路径不存在对应的内容`)response.end()}
改成读取文件
// 略response.setHeader('Content-Type', 'text/html;charset=utf-8')const string = fs.readFileSync('public/index.html')response.write(string)// 略response.setHeader('Content-Type', 'text/javascript;charset=utf-8')const string = fs.readFileSync('public/main.js')response.write(string)// 略
挑战1:加载CSS
<!DOCTYPE html><html><head><title>ajax</title><link rel="stylesheet" href="style.css"></head><body><h1>AJAX demo 2</h1><script src="/main.js"></script></body></html>
if(path === '/style.css'){response.statusCode = 200response.setHeader('Content-Type', 'text/css;charset=utf-8')const string = fs.readFileSync('public/style.css')response.write(string)response.end()}
用ajax实现
// 1. 创建HttpRequest()对象const request = new XMLHttpRequest()// 2. 调用对象的open方法,只传2个参数request.open('GET', '/style.css')// 3. 监听onload和onerror事件request.onload = ()=>{console.log(request.response)// 创建style节点const style = document.createElement("style")// 填写返回的内容style.innerHTML = request.response// 插到head里document.head.appendChild(style)}request.onerror = () =>{console.log("失败了")}// 4. 调用send方法,发送请求request.send()
挑战2: 加载JS
const request = new XMLHttpRequest()request.open('GET', '/2.js')request.onload = ()=>{console.log(request.response)const script = document.createElement('script')script.innerHTML = request.responsedocument.body.appendChild(script)}request.onerror = ()=>{}request.send()
挑战3: 加载HTML
const request = new XMLHttpRequest()request.open('GET', '/3.html')request.onload = ()=>{console.log(request.response)const div = document.createElement('div')div.innerHTML = request.responsedocument.body.appendChild(div)}request.onerror = ()=>{}request.send()
onreadystatechange
onerror没有很好的匹配ajax,因为先发明
改用onreadystatechange
XMLHttpRequest.readyState
XMLHttpRequest.status
响应分为五类:信息响应(100–199),成功响应(200–299),重定向(300–399),客户端错误(400–499)和服务器错误 (500–599)。
const request = new XMLHttpRequest()request.open('GET', '3.htm') // readyState === 1request.onreadystatechange = ()=>{if(request.readyState === 4) {// 4表示done,但不知道成功还是失败if (request.status >= 200 && request.status < 300) {const div = document.createElement('div')div.innerHTML = request.responsedocument.body.appendChild(div)} else{alert("html加载失败")}}}request.send() // readyState === 2
挑战4:加载XML
XML (Extensible Markup Language) 可扩展标记语言
<?xml version="1.0" encoding="UTF-8"?><message><warning>Hello World</warning></message>
responseXML返回dom
const request = new XMLHttpRequest()request.open('GET', '/4.xml')request.onreadystatechange = ()=>{if(request.readyState === 4) {if (request.status >= 200 && request.status < 300) {// console.log(request.responseXML) // 返回的是一个DOMconst dom = request.responseXMLconst text = dom.getElementsByTagName('warning')[0].textContent.trim()console.log(text)} else{alert("xml加载失败")}}}request.send()
挑战5:加载JSON
JavaScript Object Notation
JSON是一门标记语言,与HTML, XML, Markdown一样,用来展示数据
中文官网:http://www.json.org.cn/index.htm
JSON支持的类型:
- string
- number
- bool
- null
- object
- array
/* server.js 添加路由 */if(path === '/5.json'){response.statusCode = 200response.setHeader('Content-Type', 'text/json;charset=utf-8') // 也可以用application/jsonconst string = fs.readFileSync('public/5.json')response.write(string)response.end()}
getJSON.onclick = () => {const request = new XMLHttpRequest()request.open('GET', '/5.json')request.onreadystatechange = ()=>{if(request.readyState === 4 && request.status === 200){console.log(request.response)const obj = JSON.parse(request.response)console.log(obj)sayHi.textContent = "Hello " + obj.name}}request.send()}
window.JSON 对象
JSON.parse() 解析JSON字符串
JSON.stringify() 转成JSON字符串
JSON.parse('{"name":"rose"}')JSON.stringify({name:"rose", age:18})try{let myName = JSON.parse(`{'name':"rose"}`)}catch(error){console.log(error)}
综合:加载分页
默认加载page1
if(path === '/index.html'){response.statusCode = 200response.setHeader('Content-Type', 'text/html;charset=utf-8')let string = fs.readFileSync('public/index.html').toString()const page1 = fs.readFileSync('db/page1.json')const array = JSON.parse(page1)const result = array.map(item => `<li>${item.id}</li>`).join('')string = string.replace(`{{page1}}`,`<ul id="multiPages">${result}</ul>`)response.write(string)response.end()}
ajax请求page2
let n = 1getPage.onclick = ()=>{const request = new XMLHttpRequest()request.open('GET', `/page${n+1}.json`) // 注意,第二个参数是server.js里的路由pathrequest.onreadystatechange = ()=>{if(request.readyState === 4 && request.status === 200) {const array = JSON.parse(request.response)array.forEach(item => {const li = document.createElement('li')li.textContent = item.idmultiPages.appendChild(li)})n+=1}}request.send()}
