AJAX之前
在AJAX之前如何发送请求?
- 用form表单可以发送请求,但是会刷新页面或者新开页面
- 用a可以发送get请求,但是会刷新页面或者新开页面
- 用img可以发送get请求,但是只是以图片的形式展示
- 用link可以发送get请求,但是只能以css,favicon的形式展示
- 用script可以发送请求,但是只能以脚本的形式运行
使用img发送请求的例子:
var image =document.creatElement('img');
image.src='/xxx';
image.onload =function(){
console.log('s');
}
image.onerror = function(){
console.log('f')
}
复制代码
后来,经过漫长的等待;开发人员开始思考一个问题:
有没有什么方式可以实现,
- get,post,put,delete请求都行
- 想以什么形式展示就以什么形式展示
AJAX
Asynchrouns JavaScript And XML:异步的JavaScript和XML
- 使用XMLHttpRequest发请求
- 服务器返回了XML格式的字符串
- JavaScript解析XML,并更新局部页面
后来JSON取代了XML
if(path ==='/'){
let string =fs.readFileSync('./index.html');
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');
response.statusCode =200;
response.setHeader('Content-Type','text/javascript;charset=UTF-8')
response.write(string);
response.end();
}
//如果你请求的路径是‘/’,则执行的地址就是string指向的地址,也就是index.html
复制代码
AJAX请求的格式:
let requeset = new XMLHttpRequest()
//声明一个XMLHttpRequset()对象;
requeset.open('post','/xxx')
//配置一下XMLHttpRequset()对象;
1.请求的方式:GET/POST/PUT/delete
2.请求的地址:'URL'
3.是否异步,默认状态下就是异步
requset.send()
复制代码
当请求的地址正确,返回的XML代码格式:
if(path==='/xxx'){
response.statusCode =200;
response.setHeader('Content-Type','text/xml')
response.write(
`
"1.0" encoding="UTF-8"?>
Tove
jani
Remember
Don't forget me this weekend
`)
response.end()
}
复制代码
let requset = new XMLHttpRequset();
// request.readyState ===0
requset.open('post','/login')
//requset.readyState ===1
requset.send()
//requset.readyState ===4表示请求已经把响应下载完毕
复制代码
readyState的值为0时,表示未打开 open()方法还未被调用
readyState的值为1时,表示未发送 send()方法还未被调用
readyState的值为2时,表示已获取响应头 send()方法已经被调用,响应头和响应状态已经返回
readyState的值为3时,表示正在下载响应体
readyState的值为4时,表示整个请求的过程已经完毕
通过访问XML代码实现反馈:(已经过时)
if(requset.status >=200 && rquset.status < 300){
//直接打印xml内容
console.log(requset.responseText)
//获取XML代码
let parser = new DOMParser()
let xmlDoc = parser.parseFromString(requset.responseText,'text/xml')
let title = xmlDoc.getElementsByTagName('heading')[0].textContent
console.log(title)
}
复制代码
显然通过XML获取数据不免有些尴尬,这时候一种新的语言Json出现了
Json语法具体介绍:www.json.org
json有以下几种数据类型:string,number,object,array,true,false,null
JS和JSON的区别:
JSON没有抄袭JS的undefined和function
JSON的首尾必须是" "
string: 'xiaoming' "xiaoming"
object: {name:'xiaoming'} {"name":"xiaoming"}
undefined: undefined, /
null: null ,null
array:['a','b'] , ["a","b"]
function:function fn(){} , /
{ __proto __ }, /
使用json返回一个http字符串:
response.write(`{
"note":{
"to":"小谷",
"from":"xiaoming",
"heading":"打招呼",
"content":"hi"
}
}`)
复制代码
前端实现:
let string = requset.responseText
//下面把符合Json语法的字符串转换成JS对应的值
let obj = window.JSON.parse(string)
复制代码
同源:协议+端口+域名一模一样的称之为同源 在不同源的情况下网站是不会接受发送的AJAX请求的,所以要接受AJAX请求必须为同源策略的前提之下。 浏览器必须保证是同源才允许才送AJAX请求,但是在CORS(Cross-Origin-Resource-Sharing跨站资源共享)的条件下,相当于一个网站在发送AJAX请求的不遵守同源策略同时于给对方打了一个电话,同样可以实现请求。
响应头:
response.setHeader('Access-Control-Allow-Origin','http://bbb.com:8001')
复制代码
面试:手写一个AJAX请求
let request = new XMLHttpRequest()
request.open('post/get/put/delete','url') //配置request
requset.send()
requset.onreadyStatechange = function(){
if(request.onreadyState ===4){ //条件判断,如果状态是4,表示成功
if(request.status >=200 && request.status<300){
let string = request.responseText
let Obejct = window.JSON.parse(string)
}
}
}
复制代码
jQuery封装的AJAX的请求:
1.JS可以设置任意HTTP的header吗?
MDN地址: XMLHttpRequset.setRequsetHeader()
- 在open()和send()之间设置
- 一个value和一个key
request.setRequestHeader('xiaoming','18')
设置请求的头部: requeset.setRequestHeader('Content-Type','x-www-form-urlencoded')
JS也可以设置HTTPbody吗?requset.send("想要设置任何东西都可以在这里写啦!")
总结:
request.open('get','/xxx') //设置请求的第一部分
request.setHeader('content-type','x-www-form-urlencoded') //第二部分
request.send('啦啦啦') //第四部分 (第三部分不用设置)
//在get下 chrome不会显示啦啦啦,如果设置为post则会显示。
复制代码
2.JS可以设置获取响应header吗?console.log(request.status)
console.log(request.statusText) //ok
console.log(request.getAllResponseHeaders()) //获取响应的所有信息
console.log(request.getResponseHeader('Content-Type')) //获取Content-Type
总结:
request.status / request.statusText //第一部分 200 / OK
request.getResponseHeader() / request.getAllResponseHeaders() //第二部分
request.responseText //获取第四部分
复制代码
jQuery.Ajax
window.jQuery:
window.jQuery = function(node){
let nodes = {
0 : node,
length: 1
}
return{
addClass : function(){
}
}
}
window.jQuery.ajax:
window.jQuery.ajax = function(options){
// code
}
复制代码
使用jQuery重新写一遍:
window.jQuery.ajax = function(url, method, body, successFn, failFn){
let requset = new XMLHttpRequest()
request.open('get','/xxx')
request.onreadystatechage = () =>{
if(request.readyState === 4){
if(request.status >=200 && request.status <300){
successFn.call(undefined , request.responseText)
}
else if (request.status >= 400){
failFn.call(undefined,requset)
}
}
}
request.send(body)
}
复制代码
调用:
myButton.addEventListener('click' , function(e){
window.jQuery.ajax(
'/xxx',
'post',
'a=1&&b=2',
(responText)=>{console.log(1)},
(request)=>{console.log(2)}
)
})
复制代码
Promise
promise确定函数格式的规范
function success(responseText){console.log(responseText)}
function fail(request){console.log(request)}
myButton.addEventListener('click',(e)=>{
$.ajax({
url:'',
method:'get'
}).then(success,fail)
}
)
--------------------------------------------------------------
myButton.addEventListener('click',(e)=>{
$.ajax({
url:'',
method:'get'
}
).then(
(responseText)=>{console.log(responseText)},
(requset)=>{console.log('error')}
)
}
)
--------------------------------------------------------------
myButton.addEventListener('click',(e)=>{
$.ajax({
url:'',
method:'get'
}
).then(
(responseText)=>{console.log(responseText),return responseText },
(requset)=>{console.log('error'),return '已经处理'}
).then(
(上一次处理的结果)=>{console.log(上一次处理的结果)},
(request)=>{console.log('error')}
)
}
)
复制代码
jQuery如果发现http的content-type为text/json就会默认的将字符串转换为对象
window.jQuery.ajax = function(url, method, body,headers){
return new Promise(function(resolve , reject){
let requset = new XMLHttpRequest()
request.open(method,url)
for(let key in headers){
let value = headers[key]
request.setRequestHeader(key , value)
}
request.onreadystatechage = () =>{
if(request.readyState === 4){
if(request.status >=200 && request.status <300){
resolve.call(undefined , request.responseText)
}
else if (request.status >= 400){
reject.call(undefined,requset)
}
}
}
request.send(body)
})
}
复制代码
promise实现:
window.jQuery.ajax = function(url, method, body,headers){
return new Promise(function(resolve , reject){
let requset = new XMLHttpRequest()
request.open(method,url)
for(let key in headers){
let value = headers[key]
request.setRequestHeader(key , value)
}
request.onreadystatechage = () =>{
if(request.readyState === 4){
if(request.status >=200 && request.status <300){
resolve.call(undefined , request.responseText)
}
else if (request.status >= 400){
reject.call(undefined,requset)
}
}
}
request.send(body)
})
}
myButton.addEventListener('click' , (e)=>{
let promise = $.ajax({
url:'/xxx',
method:'get'
}).then(
(text)=>{console.log(text)},
(request)=>{console.log(request)}
)
}
)
复制代码