AJAX是什么?

异步的JavaScript和XML

  1. 使用XMLHttpRequest发送请求
  2. 服务器返回XML格式的字符串
  3. JS解析XML,并更新局部页面
现在已经很少用XML,都在用JSON!

写一个简单的AJAX:

let request = new XMLHttpRequest();
request.open('GET','http://localhost:8001');
request.onreadystatechange = () => {
    if(request.readyState ===4){
        console.log('响应完毕');
        if(request.status => 200 && request.status < 300 || request.status === 304){
            console.log('请求成功');
            let string  = request.responseText;
            let objcet  = window.JSON.parse(string);
        }
    }else if(request.status >= 400){
        console.log('请求失败')
    }
}
request.send();

readyState 请求状态

有五种状态:

0 open()方法还未被调用.
1 send()方法还未被调用.
2 send()方法已被调用,响应头和响应状态已经返回.
3 响应体下载中;responseText中已获取了部分数据.
4 整个请求过程已经完毕.

request.status 返回请求的状态码

request.responseText 返回的字符串

JSON

JS VS JSON
  1. JSON 没有undefined和funtion
  2. JSON 字符串的首尾必须是双引号””

具体对比

undefined 没有
null null
[‘a’,’b’] [“a”,”b”]
function(){} 没有
{name:’roxas’} {“name”:”roxas”}
‘roxas’ “roxas”
var a = {}
a.self = a 搞不定(没有变量)
{proto} 没有原型链

JS使用JSON

一个JSON对象

{
    "notes":{
        "from":"roxas",
        "to":"养蛇",
        "title":"打招呼",
        "contant":"你好"
    }
}

JS代码使用JSON

let request = new XMLHttprequest();
request.open('GET','URL')  //配置request
request.onreadystatechange = ()=>{
    if(request.readyState === 4) {
        if(request.status >= 200 && request.status <300 || request.status === 304){
            let string = request.responseText;
            // 把符合 JSON 语法的字符串转换成JS对应的值
            let object = window.JSON.parse(string);
            console.log(object);
        }esle if(request.status >= 400){
            console.log('说明请求失败');
        }
    }
}
request.send();

后端代码

else if(path==='url'){
    response.statusCode = 200
    response.setHeader('Content-Type', 'text/json;charset=utf-8')
    response.setHeader('Access-Control-Allow-Origin', 'http://localhsot:8001')
    response.write(`
    {
    "notes":{
        "from":"roxas",
        "to":"养蛇",
        "title":"打招呼",
        "contant":"你好"
        }
    }
    `)
    response.end()

同源策略

只有 协议+端口+域名 一模一样才允许发 AJAX 请求

例:
http://baidu.com 可以向 http://www.baidu.com 发 AJAX 请求吗 no
http://baidu.com:80 可以向 http://baidu.com:81 发 AJAX 请求吗 no

CORS可以告诉浏览器,我俩一家的,别阻止他

CORS:Cross-Origin Resource Sharing(跨源资源共享)

响应的服务器(8001)代码加入响应头:

response.setHeader('Access-Control-Allow-Origin', 'http://localhsot:8002')

AJXA获取请求与响应的所有信息

请求:

POST / HTTP/1.1
HOST: localhost:8001
Content-Type:application/x-www-url-encoded

a=1&b=2

第一部分:

request.open('POST','http://localhost:8001')

第二部分:

request.setHeader('Content-Type','x-www-form-urlencoded')

第四部分:

request.send('a=1&b=2')
响应:
HTTP/1.1 200 OK
Content-Type: text/html

<!DOCTYPE html>
<html>...</html>

第一部分:

request.status //200
request.statusText //OK

第二部分:

request.getResponseHeader() //获得值
或
request.getResponseHeaders() //获得hash

第四部分:

request.responseText

回调函数

函数用参数是一个函数,参数名字为callback

call a function
call a function back

callback

callback === function

ES6语法 解构赋值

ES5

let method = options.method;
let body = options.body;
let successFn = options.successFn;
let failFn = options.failFn;
let headers = options.headers;

ES6

let {method,body,successFn,failFn,headers} = option

封装jQuery.ajax

// 选择器,不用看
var jQuery = function(nodeOrSelector){
    let nodes = {}
    if(typeof nodeOrSelector === 'string'){
        let temp = document.querySelectorAll(nodeOrSelector);
        for(let i = 0;i<temp.length;i++){
            nodes[i] = temp[i]
        }
        nodes.length = temp.length;
    }else if(nodeOrSelector instanceof Node){
        nodes = {
            0:nodeOrSelector,
            length:1
        }
    }
    return {
        addClass:function(){},
        setText:function(){}
    }
}
window.jQuery = jQuery;
window.$ = jQuery;
//以下为ajxa代码

window.jQuery.ajax = function({url,method,body,headers}){
    return new Promise(function(resolve,reject){
        let request = new XMLHttprequest();
        request.open(method,url);
        for(let key in headers){
            let value = headers[key];
            request.setRequestHeader(key,value)
        }
        request.onreadystatechange = ()=>{
            if(request.readystates === 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);
    })
}

Promise

return new Promise (function(resolve,reject){})

function xxx(){
    return new Promise((f1,f2)=>{
        doSometing();
        setTimeout(()=>{
            //成功就调用f1,失败就调用f2
        },3000)
    })
}

xxx().then(success,fail);
//链式操作

xxx().then(success,fail).then(success,fail);