看完这篇文章,你将了解
1.XMLHttpRequest 对象简要
2.JSON 简要
3.原生 js 如何实现 JSONP
4.原生 js 如何实现 AJAX
5.同源策略与 CORS 跨域
6.其他小知识
一. 预备知识 XMLHttpRequest对象简要
属性:
xhr.responseText //收到的响应字符串
xhr.status //响应的状态码(200 404 ...)
xhr.readystate //响应下载状态0-4(含义见 六=>3)
方法:
xhr.open('GET', '/xxx') //配置请求动作与路径
xhr.setHeader('content-type', 'yyy') //配置请求头
xhr.send() //发送请求
xhr.onreadystatechange() = function(){} //监听响应下载状态
二. 预备知识 JSON简要
1.基本类型
string number boolean null object array
注意:JSON的字符串类型必须加双引号 " "
2.服务器怎么返回对象给前端?
a:服务器其实不能返回对象给前端,只能返回字符串给前端(因为HTTP响应的第四部分永远是字符串),只不过当这个字符串符合JSON对象语法时,我们可以解析出对象。
3.字符串解析为JSON对象:
let object = window.JSON.parse(string)
三. JSONP
1.什么是JSONP?
简易版:JSONP就是请求一个script,然后运行这个script。
完整版:JSONP(JSON with padding)是数据格式JSON的一种“使用模式”,可以让网页从别的网域要数据。
主要目的是实现页面与后端的无刷新交互。
主要方法是:动态创建script标签并让src指向后端,后端返回脚本内容,触发浏览器立即加载并执行相应js代码,从而实现前后端无刷新数据交互。
2.JSONP 具体写法
就是前端提供函数的定义和script,后端提供实参和调用语句。
- 请求方:创建script,src指向响应方,同时传一个查询参数?callback = xxx(xxx是请求方的一个函数)
- 响应方:根据查询参数callback获得xxx,传入数据,并返回一条调用xxx函数的js命令
- xxx这个函数名由 字符串+随机数 组成
- 监听script脚本的加载事件,无论成功与否,干掉这个脚本和随机函数
3.示例
前端代码:
button.addEventListener('click', (e)=>{
let functionName = 'frank' + parseInt(Math.random()*10000000, 10)
window[functionName] = function(result){ //每次请求之前搞出一个随机的函数名
if(result === 'success'){
amount.innerText = amount.innerText - 0 - 1
}
}
let script = document.createElement('script')
script.src = '/pay?callbacck=' + functionName
document.body.appendChild(script)
script.onload = function(e) { //状态码是200-299,则表示成功
e.currentTarget.remove() //请求完了就干掉这个脚本
delete window[functionName] //请求完了就干掉这个随机函数
}
script.onerror = function(e) { //请求码大于等于 400 则表示失败
e.currentTarget.remove()
delete window[functionName]
}
})
后端代码:
...
if( path === '/pay') {
let amount = fs.readFileSync('./db', 'utf8')
amount -= 1
fs.writeFileSync('./db', amount)
let callbackName = query.callback
response.setHeader('Content-Type', 'application/javascript')
response.write(`
$(callbackName).call(undefined, 'success')
`)
response.end()
}
...
四. AJAX
什么是AJAX?
- 简易版:就是用原生的XMLHttpRequest对象发出请求,得到服务器返回的数据后再作处理。
完整版:完整写法为async Javascript and XML:异步的javascript和XML。满足三个要求即为AJAX:
- 使用XMLHttpRequest(xhr)发请求
- 服务器返回XML格式的字符串
- JS解析XML,并局部更新页面
原生js实现AJAX
submit.onclick = function(){ let xhr = new XMLHttpRequest() xhr.open('POST', '/pay') //配置xhr xhr.send() xhr.onreadystatechange() = function() { if(xhr.readyState === 4) { if(xhr.status >=200 && xhr.status < 300) { console.log('请求成功') let str = xhr.responseText let obj = JSON.parse(str) console.log(obj) }else if(xhr.status >= 400) { console.log('请求失败') } } } }
五. 扩展知识:同源策略与CORS跨域
1.同源策略:只有 协议+域名+端口 一模一样才允许发AJAX请求
比如:如果你的页面不是http://baidu.com:8000,就不能向http://baidu.com:8000发起AJAX请求
2.CORS跨域:就是为AJAX请求的同源策略设置“例外规则”
怎么做?让后台加上一句响应头就可以了:
response.setHeader('Access-Control-Allow-Origin', "协议+域名+端口") //允许声明的例外站点访问我
3.总结:
跨域策略有两种——jsonp和cors
jsonp能跨域,这是因为它通过动态创建script实现的,本来就没有同源限制
cors能跨域,是在同源策略的限制下设置例外规则
jsonp不能发POST请求,因为script不能POST,而cors支持所有动词
六. 其他小知识
1.前端如何发请求?
form、a可以发请求:但是会刷新或新开页面
link、img可以发请求:但是只能以CSS、图片形式展示
script标签可以发请求:利用这点我们实现了jsonp
xhr对象可以发请求:利用这点我们实现了ajax
2.javascript的tic-toc:代码计时
console.time()
/*js代码*/
console.timeEnd()
3.readyState的五种状态
0: 未打开 → open()还没调用
1: 未发送 → send()还没调用
2: 已获取响应头和响应状态
3: 正在下载响应体
4: 请求完成
4.jQuery是怎么实现ajax的?
仔细观察jQuery实现ajax的一个实例
$.ajax({
type: 'post',
url: 'http://jack.com:8002/pay',
dataType: 'json',
success: function() {
console.log('请求成功')
...
},
error: function() {
console.log('请求失败')
}
})
不难发现它就是一个函数$.ajax(),传入了一个参数,只不过这个参数是一个对象而已。
//相当于
let obj = {type: xxx, url: yyy, dataType: zzz, success: function(){}, error: function(){}}
$.ajax(obj)
若对之前讲过的原生js实现ajax的代码进行优化,封装成一句api的话。可以发现:我们需要交接的所有参数,都写在这个对象的属性之中。
因此,$.ajax()这个函数,本质上就是这句优化后的api。
暂无评论