一些发请求的方法
用 form 可以发请求,但是会刷新页面或新开页面
用 a 可以发 get 请求,但是也会刷新页面或新开页面用 img 可以发 get 请求,但是只能以图片的形式展示用 link 可以发 get 请求,但是只能以 CSS、favicon 的形式展示用 script 可以发 get 请求,但是只能以脚本的形式运行()
用AJAX发请求
什么是AJAX? —— 异步的 JavaScript 和 XML
主要分为三步
- 使用XMLHttpRequest发请求
- 服务器返回XML格式的字符串
- JS解析XML,并更新局部页面(目前用替代XML)
示例代码:
Document
btn.addEventListener('click', (e) => { //第一步:使用XMLHttpRequest发请求 let request = new XMLHttpRequest() //配置request,初始化一个请求 request.open('GET', '/xxx') //发送请求 request.send() //监听请求的状态 request.onreadystatechange = () => { if (request.readyState === 4) { //,4表示请求响应都完毕 if (request.status >= 200 && request.status < 300) { console.log('请求成功') let string=request.responseText //第三步:把符合JSON语法的字符串转换成JS对应的值 let object=JSON.parse(string) } else if (request.status >= 400) { console.log('请求失败') } } } })
/********后端代码************/ if (path === '/') { let string = fs.readFileSync('./index.html', 'utf8') response.statusCode = 200 response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write(string) response.end() } else if (path === '/main.js') { let string = fs.readFileSync('./main.js', 'utf8') response.statusCode = 200 response.setHeader('Content-Type', 'text/javascript;charset=utf-8') response.write(string) response.end() } else if (path === '/xxx') { response.statusCode = 200 response.setHeader('Content-Type', 'text/json;charset=utf-8') //第二步:服务器返回XML格式的字符串(这里用JSON替代XML) response.write(` { "note":{ "to": "今天", "from": "明天", "heading": "每一天", "content": "天天" } } `) response.end() } else { response.statusCode = 404 response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write('错误') response.end() } /*********后端代码***********/
注意:
- 通过AJAX,JS 可以设置任意请求 header
第一部分 request.open('get', '/xxx')
第二部分 request.setRequestHeader('content-type','x-www-form-urlencoded') 第四部分 request.send('a=1&b=2')
- 通过AJAX,JS 可以获取任意响应 header
第一部分 request.status / request.statusText
第二部分 request.getResponseHeader() / request.getAllResponseHeaders() 第四部分 request.responseText
关于JSON
JSON是一门新语言,是一种数据格式化语言
JS和JSON的区别
JSON没有7种数据类型中的function和undefined
JSON的字符串首尾必须是双引
具体如下表:
JS | JSON |
undefined | 无 |
null | null |
['a','b'] | ["a","b"] |
function fn (){} | 无 |
{name:'frank'} | {"name":"frank"} |
'frank' | "frank" |
var a={} a.self=a | 无变量 |
{__proto__} | 没有原型链 |
关于同源策略
浏览器必须保证:
协议+端口+域名 一模一样才允许发AJAX请求,有限制,但是安全
突破同源策略(CORS跨域)
Cross-Origin Resource Sharing 跨栈资源共享
示例代码:
//发起请求request.open('GET', 'http://jerry.com:8002/xxx')
//后台添加response.setHeader('Access-Control-Allow-Origin','http://tom.com:8001')
封装AJAX
初封装
window.$=window.jQuery$.ajax=function(options){ let url=options.url let method=options.method let body=options.body let successFn=options.successFn let failFn=options.failFn let headers=options.headers //第一步:使用XMLHttpRequest发请求 let request = new XMLHttpRequest() request.open(method, url)//配置request,初始化一个请求 for(let key in headers){ let value=headers[key] request.setRequestHeaders(key,value)} request.send(body)//发送请求 //监听请求的状态 request.onreadystatechange = () => { if (request.readyState === 4) { //4表示请求响应都完毕 if (request.status >= 200 && request.status < 300) { successFn.call(undefined,request.responseText) } else if (request.status >= 400) { failFn.call(undefined,request.responseText) } } }}//**********使用**************btn.addEventListener('click', (e) => { $.ajax({ url:'/xxx', method:'POST', headers:{ 'content-typw':'application/x-www-form-urlencoded', 'today':'18'} body:'a=1&b=2', successFn:(responseText) => {console.log(1)}, failFn:(request) => {console.log(2)} })})
若接收两种参数
..........$.ajax=function(options){ let url if (arguments.length===1){ url=options.url}else if (arguments.length===2){ url=arguments[0] options=arguments[1] } let url=options.url let method=options.method let body=options.body let successFn=options.successFn let failFn=options.failFn let headers=options.headers ..........
若请求响应成功后要执行两个函数
//**********使用**************function f1(responseText){}function f1(responseText){}btn.addEventListener('click', (e) => { $.ajax({ url:'/xxx', method:'POST', body:'a=1&b=2', successFn:(x) => { f1.call(undefined,x) f2.call(undefined,x)}, failFn:(request) => {console.log(2)} })})
**举例解释ES6 解构赋值**
var a = 'a' var b = 'b' [a,b]=[b,a] a//"b" b//"a"//将b赋值给a,将a赋值给b
封装优化
window.$=window.jQuery$.ajax=function({url,method,body,headers}){ //ES6 解构赋值 return new Promise(function(resolve,reject){ let request = new XMLHttpRequest() request.open(method, url)//配置request for(let key in headers){ let value=headers[key] request.setRequestHeaders(key,value)} //监听请求的状态 request.onreadystatechange = () => { if (request.readyState === 4) { //4表示请求响应都完毕 if (request.status >= 200 && request.status < 300) { resolve.call(undefined,request.responseText) } else if (request.status >= 400) { reject.call(undefined,request) } } } request.send(body)})}//*********使用***********btn.addEventListener('click', (e) => { $.ajax({ url:'/xxx', method:'get', headers:{ 'content-type':'application/x-www-form-urlencoded', 'today':'18'} }).then( (text) => {console.log(text)}, (request) => {console.log(request)})})
使用jQuery.ajax——Promise
promise是确实能够函数形式的规范
btn.addEventListener('click', (e) => { $.ajax({ url:'/xxx', method:'GET', }).then( (responseText) => {console.log(responseText)},//成功 //console.log(responseText)的结果是个对象,因为此时响应的Content-Type是text/json,jQuery会自动将字符串转换成对象 (request) => {console.log(error)}//失败) })
如果要对一个结果进行多次处理
btn.addEventListener('click', (e) => { $.ajax({ url:'/xxx', method:'GET',}).then( (responseText) => {console.log(responseText),},//成功 (request) => {console.log(error)}//失败).then( (上次处理的结果) => { console.log(上一次的处理结果) }, (request) => {console.log(error)})})
待补充..........