nodejs+mongodb笔记------第七章(ajax)

AJAX简介
  AJAX全称Asynchronous javascript And XML,就是异步的JS和XML
  通过AJAX可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。
  AJAX不是新的编程语言,不是新的一门独立的技术,而是一种使用现有标准的新方法。

XML简介
  XML可扩展标记语言
  XML被设计用来传输和存储数据
  XML和HTML类型,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示一些数据

  比如说我有一个学生数据
    name="孙悟空";age=18;gender="男"
  用XML表示:
    <student>
      <name>孙悟空</name>
      <age>18</age>
      <gender>男</gender>
    </student>

  现在已经被JSON取代了
  用JSON表示:
    {"name":"孙悟空","age":18,"gender":"男"}

  AJAX的工作原理
    Ajax的工作原理相当于在用户和服务器之间加了一个中间层(Ajax引擎),使用户操作与服务器响应异步化。

  AJAX的特点
    AJAX的优点
      1.可以无需刷新页面而与服务器进行通信
      2.允许你根据用户事件来更新部分页面内容
    AJAX的缺点
      1.没有浏览历史,不能回退 
      2.存在跨域问题
      3.SEO不友好
  
  核心对象
    XMLHttpRequest,AJAX的所有操作都是通过该对象进行的

原生AJAX

server.js

//1.引入express
let express = require('express')

//2.创建app服务对象
let app = express()
//暴露静态资源
app.use(express.static('public'))
//解析POST请求请求体中以urlencoded形式编码参数
app.use(express.urlencoded({extended:true}))


app.get('/test_get',(request,response)=>{
  console.log('一个GET请求来了',request.query)
  response.send('我是服务器响应GET请求的信息')
})

app.post('/test_post',(request,response)=>{
  console.log(request.body)
  console.log('一个POST请求来了')
  response.send('我是服务器响应POST请求的信息')
})

//4.绑定端口监听
app.listen(3000,(err)=>{
  if (!err) {
    console.log('【不要使用webstorm打开html页面,会存在跨域问题!!用以下地址】')
    console.log('测试原生js发送Ajax-GET请求的地址是:http://localhost:3000/ajax_get.html')
    console.log('测试原生js发送Ajax-POST请求的地址是:http://localhost:3000/ajax_post.html')
    console.log('测试自己封装的Ajax请求的地址是:http://localhost:3000/ajax_with_promise.html')
  }
  else console.log(err)
})

public/ajax_get.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>测试原生jS发送Ajax-GET请求</title>
</head>
<body>

<h2>该页面是测试使用原生js发送Ajax-GET请求</h2>
<button id="btn">点我使用原生js发送Ajax-GET请求</button>
<div id="demo"></div>
<script type="text/javascript">
  /*
  * 1.实例化一个XMLHttpRequest对象。
  * 2.给该对象绑定一个事件监听,名称为:onreadystatechange。
  * 3.指定发请求的:方式、地址、参数。
  * 4.发送请求。
  * */
  
  let btn = document.getElementById('btn')
  btn.onclick = function () {
    
    //1.实例化一个XMLHttpRequest对象。
    let xhr = new XMLHttpRequest()

    //2.给该对象绑定一个事件监听,名称为:onreadystatechange。
    xhr.onreadystatechange = function () {
      /*
      * 在xhr内部有5种状态:
      *     -0:当xhr被实例化出来,状态就是0,即:初始化状态。
      *     -1:请求还没有发出去,即:send方法还没有被调用,依然可以修改请求头。
      *     -2:请求已经发出去了,即:send方法已经被调用了,不能再修改请求头,响应首行和响应头已经回来了。
      *     -3:数据回来了(但是数据可能不完整,如果数据小,会在此阶段直接接收完毕,数据大有待于进一步接收)
      *     -4:数据完全回来了
      * */
      //备注:一般不会在0、1、2、3这几种状态的回调中,做任何逻辑。
      /*if(xhr.readyState === 0){
        console.log('我出生了,我是初始化状态')
      }*/
      /*if(xhr.readyState === 1){
        xhr.setRequestHeader('demo',123)
        console.log('请求还没有发出去,即:send方法还没有被调用,依然可以修改请求头。')
      }*/
      /*if(xhr.readyState === 2){
        //xhr.setRequestHeader('demo',123)
        console.log('请求已经发出去了,即:send方法已经被调用了,不能再修改请求头,响应首行和响应头已经回来了。')
        console.log(xhr.getResponseHeader('Date'));
      }*/
      /*if(xhr.readyState === 3){
        console.log('数据回来了(但是数据可能不完整,如果数据小,会在此阶段直接接收完毕,数据大有待于进一步接收)')
        console.log(xhr.response);
      }*/
      if(xhr.readyState === 4 && xhr.status === 200){
        console.log(xhr)
        let demo = document.getElementById('demo')
        demo.innerHTML = xhr.response
      }
    }

    //3.指定发请求的:方式、地址、参数。
    xhr.open('GET','http://localhost:3000/test_get?name=kobe&age=18&t='+Date.now())
    
    //4.发送请求。
    xhr.send()
    
    /*
    * 对于IE来说:
    *   只要请求的地址不发生变化,那么直接走强缓存
    * 对于chrome和火狐
    *   请求地址不发生变化,尝试请求协商缓存。
    * */
  }
  
  
</script>

</body>
</html>

public/ajax_post.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>测试原生jS发送Ajax-POST请求</title>
</head>
<body>

<h2>该页面是测试使用原生js发送Ajax-POST请求</h2>
<button id="btn">点我使用原生js发送Ajax-POST请求</button>
<div id="demo"></div>
<script type="text/javascript">
  /*
  * 1.实例化一个XMLHttpRequest对象。
  * 2.给该对象绑定一个事件监听,名称为:onreadystatechange。
  * 3.指定发请求的:方式、地址、参数。
  * 4.发送请求。
  * */
  
  let btn = document.getElementById('btn')
  btn.onclick = function () {
    
    //1.实例化一个XMLHttpRequest对象。
    let xhr = new XMLHttpRequest()

    //2.给该对象绑定一个事件监听,名称为:onreadystatechange。
    xhr.onreadystatechange = function () {
      if(xhr.readyState === 4 && xhr.status === 200){
        console.log(xhr.response)
        let demo = document.getElementById('demo')
        demo.innerHTML = xhr.response
      }
    }

    //3.指定发请求的:方式、地址、参数。
    xhr.open('POST','http://localhost:3000/test_post')
    //设置POST请求所特有的请求头!!!!!!
    xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')

    //4.发送请求。
    xhr.send('name=kobe&age=18')
  }
  
  
</script>

</body>
</html>

数组的reduce方法

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>数组的reduce方法</title>
</head>
<body>

<script>
  /*
  * 【数组的reduce方法】:
  *   1.reduce方法接收一个函数作为累加器(“连续操作器”)。
  *   2.数组中的每个值(从左到右)开始合并(不一定是相加!),最终为一个值。
  *   3.reduce为数组中的每一个元素【依次执行】回调函数,但不包括数组中被删除或从未被赋值的元素。
  *   4.reduce方法最终返回的是最后一次调用累加器的结果。
  *   5.累加器函数接受四个参数:preValue, nowValue, nowIndex, arr
  *       --preValue:
  *             --第一次调用时是初始值,如果初始值没有指定,就是数组中第一个元素的值,同时nowValue变为数组中的第二个值。
  *             --以后调用时是上一次该回调函数的返回值;
  *       --nowValue:当前元素值;
  *       --nowIndex:当前索引;
  *       --arr:调用 reduce 的数组;
  *
  * 参数说明:
  *   array.reduce(function(preValue, nowValue, nowIndex, arr){}, initialValue)
  *
  * 注意:
  *     1.如果initialValue在调用时被提供,那么第一次的preValue就等于initialValue,nowValue等于数组中的第一个值;
  *     2.如果initialValue未被提供,那么preValue等于数组中的第一个值,nowValue自动等于数组中的第二个值。
  *
  * */
  
  let arr = [2,4,6,8]
  
  let result = arr.reduce(function (preValue, nowValue, nowIndex, arr) {
    return preValue + nowValue
  },100)
  console.log(result);

</script>
</body>
</html>

public/ajax_with_promise.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>使用Promise封装原生Ajax</title>
</head>
<body>
<h2>该页面使用Promise封装了原生Ajax</h2>
<button id="btn1">点我是我使用自己封装的方法发送GET请求</button>
<button id="btn2">点我是我使用自己封装的方法发送POST请求</button>

<script type="text/javascript">
  
  let btn1 = document.getElementById('btn1')
  let btn2 = document.getElementById('btn2')
  
  btn1.onclick = function () {
    sendAjax('http://localhost:3000/test_get','GET',{m:1,n:2}).then((data)=>{
      console.log(data)
    }).catch((err)=>{
      console.log(err)
    })
  }
  btn2.onclick = function () {
    sendAjax('http://localhost:3000/test_post','POST',{m:3,n:4}).then((data)=>{
      console.log(data)
    }).catch((err)=>{
      console.log(err)
    })
  }
  
  /*;(async()=>{
    let {data} = await sendAjax('http://localhost:3000/test_get','GET',{m:1,n:2})
    let {data2} = await sendAjax('http://localhost:3000/test_get','GET',{data})
    let {data3} = await sendAjax('http://localhost:3000/test_get','GET',{data2})
  })()*/
  
  function sendAjax(url,method,data) {
    return new Promise((resolve,reject)=>{
      //1.创建xhr对象
      let xhr = new XMLHttpRequest()
      //2.绑定监听
      xhr.onreadystatechange = function () {
        if(xhr.readyState !== 4){
          return
        }
        if(xhr.readyState === 4 && (xhr.status >= 200 && xhr.status<= 299)){
            const responseObj = {
              data:xhr.response,
              status:xhr.status,
              statusText:xhr.statusText
            }
            resolve(responseObj)
        }else{
            reject(new Error('请求出错了'))
        }
      }
      //3.设置请求的方式,地址,携带的参数
      let dataKeys = Object.keys(data)
      //4.将传递过来的数据对象加工成urlencoded形式的编码
      let str = dataKeys.reduce(function (pre,now) {
        return pre+=`${now}=${data[now]}&`
      },'')
      //5.发送请求
      if(method.toLowerCase() === 'get'){
        url += `?${str}`
        xhr.open(method,url)
        xhr.send()
      }else if (method.toLowerCase() === 'post'){
        xhr.open(method,url)
        xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')
        xhr.send(str)
      }
    })
  }
</script>

</body>
</html>

取消上一次请求

server.js

//1.引入express
let express = require('express')

//2.创建app服务对象
let app = express()
app.use(express.static('public'))

//根路由
app.get('/get_code',(request,response)=>{
  /*
  * 返回一个1000 - 9999
  * */
  console.log('客户端发来了获取验证码的请求')
  setTimeout(function () {
    let code = Math.floor(Math.random()*8999 + 1000)
    response.send(code.toString())
  },2000)
})

//4.绑定端口监听
app.listen(3000,(err)=>{
  if (!err) console.log('http://localhost:3000/')
  else console.log(err)
})

public/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>取消上一次请求</title>
</head>
<body>
<button id="btn">点我获取验证码</button>

<script type="text/javascript">
 
 let btn = document.getElementById('btn')
 let lastXhr
  btn.onclick = function () {
   if(lastXhr){
     lastXhr.abort()
   }
    lastXhr = getCode()
  }
  
  function getCode() {
    let xhr = new XMLHttpRequest()

    xhr.onreadystatechange = function () {
      if(xhr.readyState === 4 && xhr.status === 200){
        console.log(xhr.response)
      }
    }

    xhr.open('GET','http://localhost:3000/get_code')

    xhr.send()

    return xhr
    //xhr.abort()
    /*
    * abort()取消本次请求(拦截回来的响应)。
    * */
  }

</script>

</body>
</html>

jQuery封装的Ajax

server.js

//引入express框架
let express = require('express')
//创建app应用对象
let app = express()
//暴露静态资源
app.use(express.static('public'))
//引入服务器内部具体实现
app.disable('x-powered-by')
//用于解析post请求的请求体参数
app.use(express.urlencoded({extended:true}))

app.get('/test_get',(request,response)=>{
  console.log(request.query);
  console.log('test_get路由被调用了')
  response.send('我是服务器返回的GET请求的信息')
})

app.post('/test_post',(request,response)=>{
  console.log(request.body);
  console.log('test_post路由被调用了')
  response.send('我是服务器返回的POST请求的信息')
})

app.listen(3000,(err)=>{
  if(!err) console.log('测试jQuery封装的Ajax请求的地址是:http://localhost:3000/jquery_ajax.html')
  else console.log(err)
})

public/jquery_ajax.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>使用jQuery发送Ajax请求</title>
</head>
<body>
<h2>该页面是测试:jQuery发送Ajax请求</h2>

<button id="btn1">点我使用jQuery发送Ajax-GET请求</button>
<button id="btn2">点我使用jQuery发送Ajax-POST请求</button>
<script type="text/javascript" src="./js/jquery-1.12.4.js"></script>

<script type="text/javascript">
  
  let btn1 = $('#btn1')
  let btn2 = $('#btn2')
  btn1.click(function () {
    /*
    * 使用jQuery发送Ajax-GET请求几个常用的参数
    *   -method:发送请求的方式
    *   -data:要传递的数据
    *   -success:成功的回调
    *   -error:失败的回调
    * */
    
    //使用jQuery发送Ajax-GET请求(标准写法)
   $.ajax('http://localhost:3000/test_get',{
      method:'GET',
      data:{name:'kobe',age:18},
      success:function (result) {
        console.log(result)
      },
      error:function (err) {
        console.log(err)
      }
    })
    
    //使用jQuery发送Ajax-GET请求(简写)
    $.get('http://localhost:3000/test_get',{name:'kobe',age:18},(data)=>{
        console.log(data)
    })
  })

  btn2.click(function () {
    /*
    * 使用jQuery发送Ajax-GET请求几个常用的参数
    *   -method:发送请求的方式
    *   -data:要传递的数据
    *   -success:成功的回调
    *   -error:失败的回调
    * */

    //使用jQuery发送Ajax-POST请求(标准写法)
    /*$.ajax('http://localhost:3000/test_post',{
      method:'POST',
      data:{name:'kobe',age:18},
      success:function (result) {
        console.log(result)
      },
      error:function (err) {
        console.log(err)
      }
    })*/

    //使用jQuery发送Ajax-POST请求(简写)
    $.post('http://localhost:3000/test_post',{name:'kobe',age:18},(data)=>{
      console.log(data)
    })
  })
  
</script>

</body>

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