AJAX 的前因后果

扼要明白 AJAX

  1. 你才返回对象,你百口都返回对象(“你”指的是相应内容的第四部份)
  2. JS 是一门言语,JSON 是另一门言语,JSON 这门言语剽窃了 JS这门言语
  3. AJAX 就是用 JS set 请乞降get 相应
  4. 相应的第四部份是字符串,能够用 JSON 语法示意一个对象,也能够用 JSON 语法示意一个数组,还能够用 XML 语法,还能够用 HTML 语法,还能够用 CSS 语法,还能够用 JS 语法,还能够用我自创的语法

怎样发要求?

用 form 能够发要求,然则会革新页面或新开页面
用 a 能够发 get 要求,然则也会革新页面或新开页面
用 img 能够发 get 要求,然则只能以图片的情势展现
用 link 能够发 get 要求,然则只能以 CSS、favicon 的情势展现
用 script 能够发 get 要求,然则只能以剧本的情势运转(就是 JSONP 的完成道理)

有无什么体式格局能够完成

  1. get、post、put、delete 要求都行
  2. 想以什么情势展现就以什么情势展现

微软的打破

IE 5 率先在 JS 中引入 ActiveX 对象(API),使得 JS 能够直接提议 HTTP 要求。
随后 Mozilla、 Safari、 Opera 也跟进(剽窃)了,取名 XMLHttpRequest,并被归入 W3C 范例

AJAX

Jesse James Garrett 讲以下手艺取名叫做 AJAX:异步的 JavaScript 和 XML

AJAX 手艺包含以下四步:

  1. 建立 AJAX 对象, 即 XMLHttpRequest
  2. 运用 XMLHttpRequest 发要求
  3. 服务器返回 XML 花样的字符串
  4. JS 剖析 XML,并更新部分页面

AJAX demo

https://github.com/wojiaofeng…

明白 AJAX

学 AJAX 之前,须要晓得 HTTP 要求内容和 HTTP 相应内容的四个部份,以下

题目: 先生的
key: alue有很多—的是须要背的吗?

要求内容:

《AJAX 的前因后果》

相应内容:

《AJAX 的前因后果》

同时还要晓得怎样在 Chrome 上检察 HTTP request 和 HTTP response

《AJAX 的前因后果》

那末,AJAX 是什么呢?我们能够画出 ” client 和 server “ 的关联图:

《AJAX 的前因后果》

AJAX 就是在 chrome 经由历程 XMLHttpRequest 对象, 组织(set)HTTP 请乞降猎取(get)HTTP 相应的手艺

那末 AJAX 的详细完成要领是怎样的呢?

  1. JS 设置(set)恣意要求 header
    要求内容第一部份 request.open(‘get’, ‘/xxx’)
    要求内容第二部份 request.setRequestHeader(‘content-type’,’x-www-form-urlencoded’)
    要求内容第四部份 request.send(‘a=1&b=2’)
  2. JS 猎取(get)恣意相应 header
    相应内容第一部份 request.status / request.statusText
    相应内容第二部份 request.getResponseHeader() / request.getAllResponseHeaders()
    相应内容第四部份 request.responseText

jQuery 的 AJAX 完成代码迭代历程

怎样肯定写的 AJAX 代码是不是准确?将你写的代码放到 AJAX demo 的 main.js

初版:运用原生 js 中的 XMLHttpRequest 完成 ajax

//本身写的初版
myButton.addEventListener('click', function(){
  ajax()
})

function ajax(){
//相当于通知浏览器我要set Http 要求了
  var request = new XMLHttpRequest()
//对应 http 要求的第一部份
  request.open("post", "/xxx")
//对应 http 要求的第二部份
  request.setRequestHeader("name", "rjj")
  request.setRequestHeader("name", "zzz")
//对应 http 要求的第三部份,仅仅是为了便于影象
  request.onreadystatechange = function(){
    if(request.readyState === 4){
      if(request.status >= 200 && request.status < 300){
        console.log("胜利")
        console.log("request.responseText")
        console.log(request.responseText)
      }else{
        console.log("失利")
        console.log(request)
      }
    }
  }
//对应 http 要求的第四部份
  request.send("xxxxxxxxx")
}

第二版:放到函数内

把初版中的function ajax(){}内写死的内容提取出来, 用变量猎取, 代码以下:

//本身写的第二版
myButton.addEventListener('click', function(){
  ajax("post", "/xxx", {name:'rjj', sss:'zxxx'}, fffff, yyyyyy)
})

function ajax(method, path, header, successFn, failFn, body){
  var request = new XMLHttpRequest()

  request.open(method, path)

  for(var key in header){
    request.setRequestHeader(key, header[key])
  }

  request.onreadystatechange = function(){
    if(request.readyState === 4){
      if(request.status >= 200 && request.status < 300){
          //挪用 ajax 函数的胜利函数,而且往这个函数增加 request.responseText 变量作为第一个参数
        successFn.call(undefined, request.responseText)
      }else{
        failFn.call(undefined, request)
      }
    }
  }

  request.send(body)
}

function fffff(x){
  console.log(x)
  console.log("要求胜利了")
}

function yyyyyy(x){
  console.log(x)
  console.log("要求失利了了")

}

第三版:更天真的函数挪用

第二版的函数挪用着实太难用了, 基础不能在现实中运用, 我能不能革新一下?

我能不能像如许挪用函数? 注重我能够转变每一个 key: value 的位置, 还能够不设置某个 key: value

ajax({
  method: "post",
  path: "/xxx",
  header:{
    name:"rjj",
    test:"rjj111",
    test2:"rjj2222"
  }
  body: "password=xxx",
  successFn: success,
  failFn: fail
})
myButton.addEventListener('click', function(){
  ajax({
    method: "post",
    header:{
      name: "xxx",
      zzz:'xxx',
    },
    successFnAA: function(x){
      console.log(x)
    },
    failFnAA: function(x){
      console.log(x)
    },
    path: "/xxx",
  })
})

function ajax(options){

  var method = options.method
  var path = options.path
  var header = options.header
  var successFn = options.successFnAA
  var failFn = options.failFnAA
  var body = options.body

  var request = new XMLHttpRequest()

  request.open(method, path)

  for(var key in header){
    request.setRequestHeader(key, header[key])
  }

  request.onreadystatechange = function(){
    if(request.readyState === 4){
      if(request.status >= 200 && request.status < 300){
        successFn.call(undefined, request.responseText)
      }else{
        failFn.call(undefined, request)
      }
    }
  }

  request.send(body)
}

注重:

  1. successFnAA 是参数, 参数的值是一个函数, 函数的内容是function(x){console.log(x)}
  2. 然则这个函数AA没有实行, 他是在 ajax 函数内部实行, 而且往函数AA增加了一个参数(request.responseText)
  3. 函数AA叫做 callback 函数

第四版: 把他放到克己的 jQuery 上

我想把原生的 AJAX 完成代码封装到我本身写的库,应当怎样办?

制造一个对象, 把第三版的 AJAX 函数挂到这个对象上即可

myButton.addEventListener("click", function(){
$.ajax(
  {
    method: "post",
    path: "/xxx",
    header:{
      name: "xxx",
      zzz:'xxx',
    },
    successFnAA: function(x){
      console.log(x)
    },
    failFnAA: function(x){
      console.log(x)
  } 
})
})

//制造对象
window.jQuery = function(nodeOrSelector){
  var nodes = {}
  return nodes
}

//将 AJAX 函数挂到对象上
window.jQuery.ajax = function(options){

  var method = options.method
  var path = options.path
  var header = options.header
  var successFn = options.successFnAA
  var failFn = options.failFnAA
  var body = options.body

  var request = new XMLHttpRequest()

  request.open(method, path)

  for(var key in header){
    request.setRequestHeader(key, header[key])
  }

  request.onreadystatechange = function(){
    if(request.readyState === 4){
      if(request.status >= 200 && request.status < 300){
        successFn.call(undefined, request.responseText)
      }else{
        failFn.call(undefined, request)
      }
    }
  }

  request.send(body)
}

//仅仅是简写,并不主要
window.$ = window.jQuery

第五版: 运用 ES6 将代码优化(析构赋值)

  1. 原代码:

    var method = options.method
    var path = options.path
    var header = options.header
    var successFn = options.successFn
    var failFn = options.failFn
    var body = options.body
  2. 运用 ES6 代码优化:

    let {method, path, header, successFn, failFn, body} = options
  3. 再次优化:

    将上一步的代码删除, 复制{method, path, header, successFn, failFn, body}

    放到window.jQuery.ajax = function(AAA){}的AAA处

第六版: 运用 promise 一致胜利函数名和失利函数名

假如一个项目须要运用两个差别的库,那末你就必需去看这个库的代码才晓得怎样挪用胜利函数和失利函数, 所以我们运用 promise 来一致函数名,挪用这个库的时刻就不必斟酌胜利函数的名字

记着: return new Promise(function(resolve, reject){})

增加 promise 步骤

  1. 在 window.jQuery.ajax 函数内部, 剪切一切代码
  2. 在 window.jQuery.ajax 函数内部,增加return new Promise(function(resolve, reject){AAA})
  3. 在AAA地区复制代码
  4. 将 successFn 变成 resolve, 将 failFn 变成 reject

运用 promise

  1. 将挪用 jQuery.ajax 中的 successFnAA 和 failFn 及其参数内容删除
  2. jQuery.ajax()以后增加.then,个中第一个参数示意胜利函数, 第二个参数表是失利函数
myButton.addEventListener("click", function() {
    jQuery.ajax({
        method: "post",
        path: "/xxx",
        header: {
            name: "xxx",
            zzz: 'xxx'
        }
    }).then(function () {
        console.log(1)
    }, function () {
        console.log(2)
    })


})


window.jQuery = function(nodeOrSelector){
    var nodes = {}
    return nodes
}



window.jQuery.ajax = function(options){
    return new Promise(function (resolve, reject) {

        var method = options.method
        var path = options.path
        var header = options.header
        var body = options.body

        var request = new XMLHttpRequest()

        request.open(method, path)

        for (var key in header) {
            request.setRequestHeader(key, header[key])
        }

        request.onreadystatechange = function(){
            if (request.readyState === 4) {
                if (request.status >= 200 && request.status < 300) {
                    resolve.call(undefined, request.responseText)
                } else {
                    reject.call(undefined, request)
                }
            }
        }
        request.send(body)
    })
}

JSON —— 一门新言语

http://json.org

同源战略

只要 协定+端口+域名 如出一辙才许可发 AJAX 要求

如出一辙如出一辙如出一辙如出一辙如出一辙如出一辙如出一辙如出一辙

  1. http://baidu.com 能够向 http://www.baidu.com 发 AJAX 要求吗 no
  2. http://baidu.com:80 能够向 http://baidu.com:81 发 AJAX 要求吗 no

浏览器必需保证
只要 协定+端口+域名 如出一辙才许可发 AJAX 要求
CORS 能够通知浏览器,我俩一家的,别阻挠他

打破同源战略 === 跨域

Cross-Origin Resource Sharing
C O 资本R S

CORS 跨域

A网站的前端程序员打电话通知B网站的后端程序员

A前: 我想和你的网站举行交互, 你赞同吗?

B后: 我赞同

然后B后端程序员就在背景代码(相应内容)写上这一句代码:

response.setHeader("Access-Control-Allow-Origin", "http://A.com:8001"), 网站是A网站的前端程序员通知给B后端

这就是 CORS 跨域

我的 github 博客地址: https://github.com/wojiaofeng…
觉得好的能够 start ,O(∩_∩)O感谢

    原文作者:wojiaofengzhong
    原文地址: https://segmentfault.com/a/1190000012897427
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞