ajax

1.什么是ajax?

AJAX:异步(A)的 JavaScript 和 XML

为什么要引入AJAX?

回答这个问题之前,我们先看下请求是怎么发的?

用 form 可以发请求,但是会刷新页面或新开页面
用 a 可以发 get 请求,但是也会刷新页面或新开页面
用 img 可以发 get 请求,但是只能以图片的形式展示
用 link 可以发 get 请求,但是只能以 CSS、favicon 的形式展示
用 script 可以发 get 请求,但是只能以脚本的形式运行

所以,考虑到以上弊端,我们想到,有没有什么方式可以实现?

get、post、put、delete 请求都行
想以什么形式展示就以什么形式展示

为此我们引入了ajax,实际上就是为了改善,JSONP不能发送get请求之外的请求。

2.具体是使用方法如下

1.使用 XMLHttpRequest 发请求
2.服务器返回 XML 格式的字符串
3.JS 解析 XML,并更新局部页面

代码如下:

myButton.addEventListener('click', (e)=>{
  let request = new XMLHttpRequest()
  request.open('get', '/xxx') // 配置request
  request.send()
  request.onreadystatechange = ()=>{
    if(request.readyState === 4){
      console.log('请求响应都完毕了')
      console.log(request.status)
      if(request.status >= 200 && request.status < 300){
        console.log('说明请求成功')
        console.log(typeof request.responseText)
        console.log(request.responseText)
        let string = request.responseText
        // 把符合 JSON 语法的字符串
        // 转换成 JS 对应的值
        let object = window.JSON.parse(string) 
        // JSON.parse 是浏览器提供的
        console.log(typeof object)
        console.log(object)
        console.log('object.note')
        console.log(object.note)

      }else if(request.status >= 400){
        console.log('说明请求失败') 
      }

    }
  }
})


// 后端代码
  }else if(path==='/xxx'){
    response.statusCode = 200
    response.setHeader('Content-Type', 'text/json;charset=utf-8')
    response.setHeader('Access-Control-Allow-Origin', 'http://frank.com:8001')
    //这里是JSON的写法,具体语法下面会具体分析
    response.write(`
    {
      "note":{
        "to": "小谷",
        "from": "方方",
        "heading": "打招呼",
        "content": "hi"
      }
    }
    `)
    response.end()

3.JSON

1.JSON是ajax中XML的上位替代,JSON是一种仿javasricpt的新语法,JSON用“”来表示字符串

2.JSON没有undefined和function

3.,没有变量,没有原型链,搞不定

var a = {}
a.self = a
{__proto__}

4.写个例子

{
    "note":{
        "to":"name",
        "from":"who"
    }
}

4.同源策略

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

一模一样一模一样一模一样一模一样一模一样一模一样一模一样一模一样

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

浏览器必须保证
只有 协议+端口+域名 一模一样才允许发 AJAX 请求

为什么???

因为页面如果是用form表单提交到另一个域名,原页面的简本无法获取新的页面中的内容。浏览器是安全的。
但是浏览器可以读取响应的内容的(request.responseText)的,因此浏览器是不允许你这样做的。
也就是说,你可以用ajax读取页面上的信息,比如(支付宝余额,好友信息),这是没有隐私可言的,所以浏览器是不允许的。
不过如果你用Ajax向不是同源的网页发送请求,其实请求已经发出去了,你只是拿不到而已。

怎么解决这个问题?

突破同源策略就行了

使用CORS 可以告诉浏览器,我俩一家的,别阻止他
突破同源策略 === 跨域

Cross-Origin Resource Sharing
C O源 R S

CORS 跨域

使用方法如下

response.setHeader('Access-Control-Allow-Origin','http://www.baidu.com//可以跨到这里去')

总结

AJAX 的所有功能

客户端的JS发起请求(浏览器上的)
服务端的JS发送响应(Node.js上的)

JS 可以设置任意请求 header 吗?
第一部分 request.open('get', '/xxx')
第二部分 request.setRequestHeader('content-type','x-www-form-urlencoded')
第四部分 request.send('a=1&b=2')

JS 可以获取任意响应 header 吗?
第一部分 request.status / request.statusText
第二部分 request.getResponseHeader() / request.getAllResponseHeaders()
第四部分 request.responseText

tips:一个问题
浏览器是一开始就知道状态码是200还是404,还是接受完请求体之后才响应200,404的
解:一开始就知道
这个问题,要从输入网址到最终响应的这个问题答起。(这个面试题很经典)
说到响应的时候,你只要说响应的时候会会先响应200还是404
但是在开发中,我们要获得响应内容,所以要先等响应结束(request.readystate === 4)
不然没法获得的

5.手写一个ajax(就是把上面的东西封装起来)

优化之后的代码如下
window.jQuery = function(nodeOrSelector){
  let nodes = {}
  nodes.addClass = function(){}
  nodes.html = function(){}
  return nodes
}
window.$ = window.jQuery

window.Promise = function(fn){
  // ...
  return {
    then: function(){}
  }
}

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

myButton.addEventListener('click', (e)=>{
  let promise = window.jQuery.ajax({
    url: '/xxx',
    method: 'get',
    headers: {
      'content-type':'application/x-www-form-urlencoded',
      'frank': '18'
    }
  })

  promise.then(
    (text)=>{console.log(text)},
    (request)=>{console.log(request)}
  )

})

这里有几个要注意的几个问题?

1.什么是回调函数?
简单说就是,使用一个函数,让另一个函数来调用它,就是回调callback
举个例子,A有把抢,给B,让B开枪杀了自己,A自己不开枪。

2.这个then是干什么用的,promise是干什么的?

因为每个程序员的回调名不一样,回调的方式很多,例如上面一开始是用success和fail,来表示响应是否成功,但是有些人用successFn和failFn,或者别的什么来表示同样的东西,难道我们用的时候要从上往下看,一点点找吗?这个太蠢了。所以要引入promise

具体使用方法如下:

在ajax.then(‘success’,'faile'),success和fail中可以直接写代码,默认第一个就是响应成功的时候,第二个是不成功。

优点1.不需要给success和fali赋值

优点2.ajax.then().then()表示进行完第一个then然后使用第一个then的返回值,当作第二个then的传入参数,表示一个链式操作

优点3.返回的requestText是一个对象,本身应该是一个字符串,但是content-type:text/json,会自动将字符串转换成对象。方便操作。

6.Promise对象

return new Promise(function(resolve,reject){
        //写代码
        }

这句话要被背下来

从上面的例子,我们可以看出Promise对象接收一个函数,并返回一个带有then属性的hash,then也是接受2个函数,并返回一个带then的hash

resolve :表示成功了就调这个
reject:表示失败了就调这个

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,123评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,031评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,723评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,357评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,412评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,760评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,904评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,672评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,118评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,456评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,599评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,264评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,857评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,731评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,956评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,286评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,465评论 2 348

推荐阅读更多精彩内容