免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Javascript 內(nèi)置方法之 XMLHttpRequest

XMLHttpRequest 類

XMLHttpRequest 為 ajax 的核心。

  • 使用
var xhr = new XMLHttpRequest()
  • XMLHttpRequest 本質(zhì)及構(gòu)成

本質(zhì)為一個函數(shù);

typeof XMLHttpRequest ; // 'function'

原型鏈關系:XMLHttpRequest “繼承”于 XMLHttpRequestEventTarget,XMLHttpRequestEventTarget “繼承”于 EventTarget ;

var xhr = new XMLHttpRequest();xhr instanceof XMLHttpRequest; // truexhr instanceof XMLHttpRequestEventTarget ; // truexhr instanceof EventTarget ; // true
  • 實例化時屬性,xhr 上屬性

    • 事件綁定

    • onabort =》中止請求時觸發(fā)

    • onerror =》請求錯誤時觸發(fā)
    • onload =》請求成功時觸發(fā)
    • onloadend =》請求不管成功失敗中止都將最后觸發(fā)
    • onloadstart => 客戶端開始發(fā)出請求,readyState=1,status=0,
    • onprogrress =》服務器已經(jīng)響應,處理請求中觸發(fā)
    • onreadystatechange =》 readyState 改變時觸發(fā)
    • ontimeout =》超時觸發(fā)

    • 響應體相關

    • readyState =》初始值為0,在 new XMLHttpRequest() 的時候

    • response
    • responseText
    • responseType
    • responseURL
    • responseXML

    • 狀態(tài)相關

    • status

    • readyState
    • statusText

    • 其他

    • timeout =》設置超時請求的時間,默認為0,不計超時
    • upload =》 XMLHttpRequestLoad 實例
    • withCredentials =》Request Header 是否帶 cookie,需服務端配合。
  • 第一層原型,XMLHttpRequest 屬性和方法

    • 屬性
    • 狀態(tài)
      • UNSENT :0
      • OPENED:1
      • HEADERS_RECEIVED:2
      • LOADING:3
      • DONE:4
    • 方法
    • abort =》中止請求
    • getAllResponseHeaders =》 獲取所有 headers 頭部信息,并非所有都能獲取
    • getResponseHeader(‘key’) =》獲取 key 的 header 信息,并非所有都能獲取
    • open(method,url,async) 打開一個請求,此時 xhr.readyState 為 1
    • overrideMimeType
    • send(data?) =》發(fā)送請求

    • 其他

    設置了 xhr 的所有屬性的 getter 和 setter

  • 第二層原型,XMLHttpRequestEventTarget

    僅設置了 xhr 的 事件綁定中的方法的 getter 和 setter

  • 第三層原型,EventTarget

    • addEventListener
    • dispatchEvent
    • removeEventListener

流程解析

前端測試代碼如下:

var xhr = new XMLHttpRequest()console.log(xhr.readyState); // 此時的 readyState 為0var eventKeys = [    'abort',    'error',    'load',    'loadend',    'loadstart',    'progress',    'readystatechange',    'timeout']eventKeys.forEach(key => {    xhr[`on${key}`] = function () {        console.log(`-------request is ${key}-------`)        console.log(`request is on${key}`)        log()        console.log('\n\n')    }});xhr.open('get', 'http://localhost:9000/', true);xhr.send()function log() {    console.log('readyState=', xhr.readyState);    console.log('status=', xhr.status);    console.log('statusText', xhr.statusText);}

nodejs 服務端代碼如下:

const Koa = require('koa');const app = new Koa();function response() {  return new Promise((resolve, reject) => {    setTimeout(() => {      resolve('hello world')    }, 10000);  })}app.use(async ctx => {  ctx.set("Access-Control-Allow-Origin", "*");  ctx.set('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');  ctx.set("Access-Control-Allow-Headers", "X-Requested-With");  ctx.set('Access-Control-Allow-Headers', 'Content-Type');  var res = await response()  ctx.body = res;})app.listen(9000)

根據(jù)打印信息,成功的普通請求概括如下:

  • readyState 經(jīng)歷四個值: 0 -》1 -》 2 -》 3 -》 4
  • 綁定事件觸發(fā)順序及對應的 readyState 是:onreadystatechange(1) -》onloadstart(1) -》 onreadystatechange(2) -》onreadystatechange(3)-》onprogress(3)-》onreadystatechange(4)-》onload(4)-》onloadend(4)
  • status :0 和 200
  • statusText:空 和 OK

通過 readyState 看請求周期

  • var xhr = new XMLHttpRequest(); // xhr.readyState = 0
  • xhr.open(‘get’,’url’,true); // readyState = 0 =》 readyState = 1 ,ononreadystatechange 觸發(fā)
  • xhr.send(); // => xhr.onloadstart() 觸發(fā),readyState 不變?yōu)?
  • readyState = 1 =》 readyState = 2,onreadystatechange 觸發(fā),服務器端已經(jīng)接收到請求。
  • readyState = 2 =》 readyState = 3,onreadystatechange 觸發(fā),并觸發(fā) onprogress 事件,表示響應正在加載中。。。
  • readyState = 3 =》 readyState = 4,onreadystatechange 觸發(fā),并觸發(fā) onload 事件。
  • 觸發(fā) onloadend 事件。

實例解析

  • 普通的 get 請求
var xhr = new XMLHttpRequest()xhr.onload = function () {    console.log(xhr.response, xhr.responseText)}xhr.open('get', 'http://localhost:9000/', true)xhr.send();
  • 普通的 post 請求(Form Data,請求參數(shù)為 key value 形式)
var xhr = new XMLHttpRequest();xhr.onload = function () {    console.log(xhr.response, xhr.responseText)}xhr.open('post', 'http://localhost:9000/', true)xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')xhr.send('name=tom&age=18');

設置請求的格式為 x-www-form-urlencoded , 且傳遞的數(shù)據(jù)為字符串,用 & 連接不同的字段。

設置請求頭,xhr.setRequestHeader( key,val )

  • 普通的 post 請求 (請求體為 json 格式)
var xhr = new XMLHttpRequest();xhr.onload = function () {    console.log(xhr.response, xhr.responseText)}xhr.open('post', 'http://localhost:9000/', true)xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");xhr.send(JSON.stringify({ name: 'tom', age: 18 }));
  • 設置超時請求( xhr.timeout=2000 )
var xhr = new XMLHttpRequest()xhr.ontimeout = function(){    console.log(xhr.status,xhr.readyState,xhr.responseText)    console.log('請求超時')}xhr.onloadend = function(){    console.log(xhr.status,xhr.readyState,xhr.responseText)    console.log('請求結(jié)束')}xhr.onreadystatechange =function(){    console.log('readyState change',xhr.readyState)}xhr.timeout = 2000xhr.open('get', 'http://localhost:9000/', true);xhr.send();

超出設置的 timeout 時間的請求,結(jié)束時,并不會觸發(fā) onerror 和 onabort 以及 onload ,只會觸發(fā) ontimeout 和 onloadend;

readyState 從 0-》1-》4

onload 和 onloadend 的區(qū)別是,onloadend 不管請求成功與否都會觸發(fā),而 onload 只有請求成功結(jié)束時觸發(fā)。

  • setRequestHeader 的用法,可以在 Request Header 中添加字段及值

客戶端

var xhr = new XMLHttpRequest()xhr.onload = function () {    console.log('請求成功')}xhr.open('post', 'http://localhost:9000/', true);xhr.setRequestHeader('X-user','tom')xhr.setRequestHeader('X-token','ACDFWE@123123')xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");xhr.send();

服務器端(nodejs),設置允許傳遞的請求頭字段,多個字段用逗號隔開。

app.use(async ctx => {  let origin = ctx.request.header.origin  ctx.set("Access-Control-Allow-Origin", origin);  ctx.set('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');  ctx.set("Access-Control-Allow-Headers", "X-user,X-token,Content-Type");  var res = await response()  ctx.body = res;})

跨越時,需要設置 Access-Control-Allow-Origin 為發(fā)送請求的客戶端的域名。

字段不區(qū)分大小寫。

  • withCredentials 的用法,請求頭中帶 cookie 信息

客戶端設置 xhr 實體 withCredentials 屬性為 true

var xhr = new XMLHttpRequest()xhr.onload = function () {    console.log('請求成功')}xhr.open('post', 'http://localhost:9000/', true);xhr.withCredentials = true; // herexhr.send();

服務端,設置允許

app.use(async ctx => {  let origin = ctx.request.header.origin  ctx.set("Access-Control-Allow-Origin", origin);  ctx.set('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');  ctx.set("Access-Control-Allow-Headers", "x-user,x-token,content-type");  ctx.set("Access-Control-Allow-Credentials", true); // here  var res = await response()  ctx.body = res;})

效果則是:

  1. Response Headers 中多了一條:Access-Control-Allow-Credentials: true
  2. Request Headers 中多了一條:Cookie:本地的 cookie 字符串

而且此時跨域的 options 請求好像也不發(fā)了

  • abort 手動終止請求
var xhr = new XMLHttpRequest()xhr.open('post', 'http://localhost:9000/', true);xhr.send();setTimeout(() => {    xhr.abort();}, 3000);

手動 abort 必須在請求完成(onloadend)之前。

周期中能觸發(fā)的事件有:onreadystatechange ,onloadstart,onprogress,onabort,onloadend

  • overrideMimeType 和 自定義返回類型
var xhr = new XMLHttpRequest()xhr.onload = function(){    console.log(xhr.response)}xhr.open('post', 'http://localhost:9000/', true);xhr.overrideMimeType('text/plain; charset=x-user-defined');// 或// xhr.responseType = 'blob';xhr.send();
  • upload 實體使用,實現(xiàn)上傳進度獲取
xhr.onprogress = updateProgress;xhr.upload.onprogress = updateProgress;function updateProgress(event) {    if (event.lengthComputable) {      var completedPercent = event.loaded / event.total;    } }
  • 簡單地封裝 ajax 請求
// ajax 方法定義function ajax(options) {    var { url, method, data, headers } = options;    var lowerMethod = method.toLowerCase();    var _isGet = lowerMethod === 'get';    var _isPost = lowerMethod === 'post';    function _dataStringify(_data) {        return Object.keys(_data).map(key => `${key}=${_data[key]}`).join('&')    }    // 拼接 data    let requestData = null    if (_isGet) {        url += `?${_dataStringify(data)}`    }    else if (_isPost) {        requestData = options.format === 'json'            ? JSON.stringify(data)        : _dataStringify(data)    }    return new Promise((resolve, reject) => {        var xhr = new XMLHttpRequest();        xhr.withCredentials = Boolean(options.withCredentials);        xhr.onload = function () {            if (xhr.status == 200 || xhr.status == 304) {                resolve(xhr.responseText);            }            else {                reject('請求錯誤')            }        }        // 綁定自定義 handler        for (var ev in options.handlers) {            var _prevHandler = xhr[ev];            xhr[ev] = function () {                _prevHandler();                options.handlers[ev]();            }        }        xhr.open(method, url, true);        // 設置 header        for (var attr in headers) {            xhr.setRequestHeader(attr, headers[attr]);        }        xhr.send(requestData);    })}// ajax 使用ajax({    url: 'http://localhost:9000',    method: 'POST',    format: 'json',    data: {        name: 'tom'    },    headers: {        // 'Content-Type': 'application/x-www-form-urlencoded',        'Content-Type': 'application/json',        'x-token': 'xxxxx'    },    withCredentials: true,    handlers: {        'onload': function () {            console.log('自定義onload')        }    }})    .then(res => {    console.log(res,222222)})    .catch(err => {    console.log(err)})

示例并不完整,可以把文件上傳的 FormData 方式添加進去,還有超時等功能。

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Ajax GET請求應用
重拾Ajax | Aitter's Blog
解讀Ajax原理是什么?如何實現(xiàn)?
Ajax實時驗證用戶名/郵箱等是否已經(jīng)存在
AJAX請求的五個步驟及步驟詳解
控制臺測試ajax
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服