AJAX

Asynchronous JavaScript And XML

通过 AJAX 可以在 浏览器中向 服务器 发送异步请求

一种 使用现有标准的 新方法,而非新语言

  • XML 

可扩展标记语言

被设计用来传输和存储数据

被 JSON 替代,JSON 内容更少,解析更方便

和 HTML 类似,不同的是

  • HTML 都是预定义标签
  • XML 全部是自定义标签,用来表示一些数据
  • AJAX 工作原理

相当于在 用户 和 服务器 之间加了一个中间层(AJAX 引擎)

使得 用户操作 和 服务器响应 异步化

1. 原生 AJAX(不要通过 webstorm 启动页面,否则会发生 跨域 错误)

// 1. 创建 xhr 对象

const xhr = new XMLHttpRequest();

// 2. 设置事件监听

xhr.onreadystatechange = function(){    // 会监听 readyState 值的变化

if (xhr.readyState === 2) {

console.log(xhr.status);
console.log(xhr.getResponseHeader('Content-Type'));

}
if (xhr.readyState === 3) {

console.log(xhr.responseText);

}

if(xhr.readyState === 4 && xhr.status === 200){    // 响应成功

console.log(xhr.responseText);    // 响应数据

};

};

/****

前端面试题:

readyState

0        xhr 对象创建成功,但是 xhr.open() 还未调用

1        open() 已经调用了,但是还未调用 send() (意味着还没有发送请求,还可以设置请求头信息)

2        send() 已经调用了,接收到部分响应数据(响应首行、响应头,没接到响应体)

3        接收到了响应体数据(如果响应体较小,或者纯文体,在此阶段就全部接收完了)

4        接收完全部的响应体数据(数据较大,或者音视频资源)

****/

// 3. 设置请求信息    设置请求方式、地址、参数

xhr.open("GET", "http://localhost:3000/ajax?username=jack&age=18");

// 还能设置请求头 xhr.setRequestHeader();

xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');

/****

必须要设置 请求头 标准规范(有三种常见规范),否则不会解析请求参数

chrome 和 FireFox    第二次及以后默认走协商缓存,状态码 304,且还会向服务器发送请求

ie    第二次及以后 get 请求 默认走强制缓存,状态码 200,且不会向服务器发送请求

需求: 股票 需要实时更新信息,此时就不能从缓存里找

解决 ie 的缓存问题:

让每一次的请求不一样

只要请求不一样,就不会走缓存

xhr.open("GET", "http://localhost:3000/ajax?username=jack&age=18&date="+Date.now());

****/

// 4. 发送请求

xhr.send();

// post 发送数据 必须以 urlencode 格式,即查询字符串去掉?,即 key=value的方式,多个键值对之间以 & 连接

  • 源码实例
  • node.js 服务器

index.js

  • const express = require('express');
    
    const app = express();
    
    app.use(express.static("public"));
    app.use(express.urlencoded({extended: true})); app.get("/", (request, response)=>{
    response.sendFile("./public/idnex.html");
    }); // 原生 ajax 的 get 路由
    app.get("/ajax", (request, response)=>{
    console.log('----get 接收的 浏览器数据: ');
    console.log(request.query); // {}
    console.log(request.body); // get 请求体 始终为空
    console.log('----'); response.send({name: '服务器 get 响应', line: 15});
    });
    // 原生 ajax 的 post 路由
    app.post("/ajax", (request, response)=>{
    console.log('----post 接收的 浏览器数据: ');
    console.log(request.query); // {} 可以有 请求字符串
    console.log(request.body); // post请求体 数据{ username: 'jack', age: '18' }
    console.log('----'); response.send({name: '服务器 post 响应', line: 21});
    });
    /**************** 端口号 3000, 启动服务器 ***************/
    app.listen(3000, err=>console.log(err?err:'\n\n服务器已启动: http://localhost:3000\n\t\tHunting Happy!'));
  • 浏览器前端代码

index.html

  • <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8"/>
    <title>原生 ajax</title>
    </head> <body> <button id="get_btn">get</button>
    <button id="post_btn">post</button> <script type="text/javascript" src="js/index.js"></script>
    </body>
    </html>

js/index.js

  • window.addEventListener('DOMContentLoaded', function () {
    const getBtn = document.getElementById("get_btn");
    const postBtn = document.getElementById("post_btn"); getBtn.onclick = function () {
    // 1. 创建 xhr 对象
    const xhr = new XMLHttpRequest(); // 2. 设置事件监听
    xhr.onreadystatechange = function () {
    if (xhr.readyState === 2) {
    console.log(xhr.status); // 状态码
    console.log(xhr.getResponseHeader('Content-Type')); // 请求头 信息
    };
    if (xhr.readyState === 3) {
    console.log(xhr.responseText); // 服务器响应 数据
    };
    if(xhr.readyState === 4 && xhr.status === 200){
    console.log(xhr.responseText); // 服务器响应 数据
    };
    }; // 3. 设置请求方式、请求地址、请求参数
    xhr.open("GET", "http://localhost:3000/ajax?username=get&get=get"); // 4. 设置请求头
    xhr.setRequestHeader('get-x', 'get'); // 5. 发送请求
    xhr.send('request=get&get=get'); // get 请求体为空,所以这里传的参数,无效
    }; postBtn.onclick = function () {
    // 1. 创建 xhr 对象
    const xhr = new XMLHttpRequest(); // 2. 设置事件监听
    xhr.onreadystatechange = function () {
    if (xhr.readyState === 2) {
    console.log(xhr.status);
    console.log(xhr.getResponseHeader('Content-Type'));
    }
    if (xhr.readyState === 3) {
    console.log(xhr.responseText);
    }
    if(xhr.readyState === 4 && xhr.status === 200){
    console.log(xhr.responseText);
    };
    }; // 3. 设置请求方式、请求地址、请求参数
    xhr.open("POST", "http://localhost:3000/ajax?username=post&post=post"); // 4. 设置请求头
    xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded'); // 5. 发送请求
    xhr.send('request=post&post=post');
    };
    }, false);

2. jQuery 中的 AJAX 请求

  • node.js 服务器

index.js

  • const express = require('express');
    
    const app = express();
    
    app.use(express.static("public"));
    app.use(express.urlencoded({extended: true})); app.get("/", (request, response)=>{
    response.sendFile("./public/idnex.html");
    }); // 原生 ajax 的 get 路由
    app.get("/jquery_ajax", (request, response)=>{
    console.log('----get 接收的 浏览器数据: ');
    console.log(request.query); // {}
    console.log(request.body); // get 请求体 始终为空
    console.log('----'); response.send({name: '服务器 get 响应', line: 15});
    }); // 原生 ajax 的 post 路由
    app.post("/jquery_ajax", (request, response)=>{
    console.log('----post 接收的 浏览器数据: ');
    console.log(request.query); // {} 可以有 请求字符串
    console.log(request.body); // post请求体 数据{ username: 'jack', age: '18' }
    console.log('----'); response.send({name: '服务器 post 响应', line: 21});
    }); /**************** 端口号 3000, 启动服务器 ***************/
    app.listen(3000, err=>console.log(err?err:'\n\n服务器已启动: http://localhost:3000\n\t\tHunting Happy!'));
  • 浏览器前端代码

index.html

  • <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8"/>
    <title>jQuery 中的 ajax</title>
    </head> <body> <button id="get_btn">get</button>
    <button id="post_btn">post</button> <script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
    <script type="text/javascript" src="js/jquery_ajax.js"></script>
    </body>
    </html>

index.js

  • window.addEventListener('DOMContentLoaded', function () {
    const getBtn = document.getElementById("get_btn");
    const postBtn = document.getElementById("post_btn"); getBtn.onclick = function () {
    $.ajax('http://localhost:3000/jquery_ajax', {
    method: 'GET', // 可以直接换成 POST,库解决好了请求头和兼容等一系列问题
    data: {
    getrequest:'Browser',
    age:10
    },
    headers: {
    'get-xxx': 'xxxx'
    },
    success: function (server_info) {
    console.log('请求成功的回调函数');
    console.log(server_info); // 自动将 json 字符串 转换成 JSON 对象
    },
    error: function (err) {
    console.log('请求失败的回调函数');
    console.log(err);
    }
    });
    }; postBtn.onclick = function () {
    $.get( // 可以直接换成 post,库解决好了请求头和兼容等一系列问题
    'http://localhost:3000/jquery_ajax',
    {postrequest:'Browser', age:26},
    function (server_info) {
    console.log(server_info);
    });
    };
    }, false);

三级联动 选择(省-市-县)

  • 服务器 index.js
  • const express = require('express');
    const promiseConnect = require('./db/connectDB.js');
    const citiesModel = require('./models/userModel.js');
    const app = express(); (async ()=>{
    const ret = await promiseConnect;
    console.log(ret); app.use(express.static("public"));
    app.use(express.urlencoded({extended: true})); app.get("/", (request, response)=>{
    response.sendFile("./public/index.html");
    }); // 省 的 get 路由
    app.get("/province", async (request, response)=>{
    try{
    const province = await citiesModel.find({"level": 1}, {"province": 1, "name": 1, "_id": 0});
    response.json({code: 200, data: province});
    }catch(err){
    console.log(err);
    response.json({code: 404, data: '网络不稳定,请刷新重试'});
    };
    }); // 市 的 get 路由
    app.get("/city", async (request, response)=>{
    try{
    const {province} = request.query;
    const city = await citiesModel.find({province, "level": 2}, {"city": 1, "name": 1, "_id": 0});
    response.json({code: 200, data: city});
    }catch(err){
    console.log(err);
    response.json({code: 404, data: '网络不稳定,请刷新重试'});
    };
    }); // 县 的 get 路由
    app.get("/county", async (request, response)=>{
    try{
    const {province, city} = request.query;
    const county = await citiesModel.find({province, city, "level": 3}, {"county": 1, "name": 1, "_id": 0});
    response.json({code: 200, data: county});
    }catch(err){
    console.log(err);
    response.json({code: 404, data: '网络不稳定,请刷新重试'});
    };
    });
    })().catch(err=>console.log(err)); /**************** 端口号 3000, 启动服务器 ***************/
    app.listen(3000, err=>console.log(err?err:'\n\n服务器已启动: http://localhost:3000\n\t\tHunting Happy!'));
  • 浏览器前端 index.html
  • <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8"/>
    <title>三级联动-省-市-县</title>
    <link rel="stylesheet" href="./css/index.css">
    </head> <body>
    <div id="outer_box">
    <select id="province">
    <option>请选择省份</option>
    </select>省 <select id="city">
    <option>请选择市</option>
    </select>市 <select id="county">
    <option>请选择区(县)</option>
    </select>区(县)
    </div> <script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
    <script type="text/javascript" src="./js/jquery_ajax.js"></script>
    </body>
    </html>

index.css

  • html, body {
    width: 100%;
    height: 100%; color: #000;
    background: #b9c2a4;
    background-size: cover; /* 指定背景图片大小 */
    } /*************************************************/
    #outer_box {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    } #outer_box select {
    width: 152px;
    font-size: 16px;
    background-color: #aec57e;
    cursor: pointer;
    }
  • 选择省份

为了避免重排 重绘,使用拼串,最后一次追加

  • 选择市

监听 表单的 change 事件

  • 选择县
  • jquery_ajax.js
  • $(function () {
    const $province = $("#province");
    const $city = $("#city");
    const $county = $("#county"); // 进入页面 首先渲染省份
    $.get("http://localhost:3000/province", function({code, data}){
    if(code === 200){
    let htmlStr = '<option>请选择省份</option>';
    data.forEach(each=>{
    /* <option value="44">广东省</option> */
    htmlStr += `<option value="${each.province}">${each.name}</option>`;
    });
    $province.html(htmlStr);
    }else{
    alert(data); // 网络不稳定,请刷新重试
    };
    }); // 省 改变出现 市
    $province.on("change", function(){
    const province = this.value; /* <option value="11">北京</option> */
    $.get('/city', {province}, function({code, data}){
    if(code === 200){
    let htmlStr = '<option>请选择市</option>';
    data.forEach(each=>{
    /* <option value="03">深圳市</option> */
    htmlStr += `<option value="${each.city}">${each.name}</option>`;
    });
    $city.html(htmlStr);
    }else{
    alert(data); // 网络不稳定,请刷新重试
    };
    });
    }); // 市 改变出现 县
    $city.on("change", function(){
    const province = $province.val(); /* <option value="11">北京</option> */
    const city = $city.val(); /* <option value="undefined">鞍山市</option> */
    console.log({province, city});
    $.get('/county', {province, city}, function({code, data}){
    if(code === 200){
    let htmlStr = '<option>请选择市</option>';
    data.forEach(each=>{
    /* <option value="06">宝安区</option> */
    htmlStr += `<option value="${each.county}">${each.name}</option>`;
    });
    $county.html(htmlStr);
    }else{
    alert(data); // 网络不稳定,请刷新重试
    };
    });
    });
    });

在 jQuery 中 $.get("http://localhost:3000/city", function({code, data}){}); 对于同一域名,可以简写为

  • $.get("/city", function({code, data}){});

1. 引入 第三方 js库 art-template

<script type="text/javascript" src="./js/template-web.js"></script>

2. 新建 <script> 标签,并设置 id 以供渲染

3.

源码由上方代码改变

  • index.html
  • <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8"/>
    <title>jQuery 中的 ajax</title>
    <link rel="stylesheet" href="./css/index.css">
    </head> <body>
    <div id="outer_box">
    <select id="province">
    <option>请选择省份</option>
    </select>省 <select id="city">
    <option>请选择市</option>
    </select>市 <select id="county">
    <option>请选择区(县)</option>
    </select>区(县)
    </div> <script type="text/html" id="templateScript">
    <option>{{firstOption}}</option>
    {{each data}}
    <option value="{{$value[name]}}">{{$value.name}}</option>
    {{/each}}
    </script>
    <script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
    <script type="text/javascript" src="./js/template-web.js"></script>
    <script type="text/javascript" src="./js/jquery_ajax.js"></script> <!-- 注意编写顺序 -->
    </body>
    </html>
  • jquery_ajax.js
  • $(function () {
    const $province = $("#province");
    const $city = $("#city");
    const $county = $("#county"); // 进入页面 首先渲染省份
    $.get("http://localhost:3000/province", function({code, data}){
    if(code === 200){
    const htmlStr = template(
    'templateScript',
    {data, firstOption: '请选择省份', name: 'province'
    }
    );

    $province.html(htmlStr);
    }else{
    alert(data); // 网络不稳定,请刷新重试
    };
    }); // 省 改变出现 市
    $province.on("change", function(){
    const province = this.value; /* <option value="11">北京</option> */
    $.get('/city', {province}, function({code, data}){
    if(code === 200){
    const htmlStr = template(
    'templateScript',
    {data, firstOption: '请选择市', name: 'city'
    }
    );

    $city.html(htmlStr);
    }else{
    alert(data); // 网络不稳定,请刷新重试
    };
    });
    }); // 市 改变出现 县
    $city.on("change", function(){
    const province = $province.val(); /* <option value="11">北京</option> */
    const city = $city.val(); /* <option value="undefined">鞍山市</option> */
    $.get('/county', {province, city}, function({code, data}){
    if(code === 200){
    const htmlStr = template(
    'templateScript',
    {data, firstOption: '请选择区县', name: 'county'
    }
    );

    $county.html(htmlStr);
    }else{
    alert(data); // 网络不稳定,请刷新重试
    };
    });
    });
    });

Ajax_简介: 异步的 JS 和 XML_原生写 ajax 分析其原理_jquery_ajax_art-template的更多相关文章

  1. Ajax:异步的JS和XML

    1.Ajax1) AJAX 是 Asynchronous JavaScript And XML 的简称.直译为,异步的JS和XML.2) AJAX的实际意义是,不发生页面跳转.异步载入内容并改写页面内 ...

  2. 原生js写Ajax

    //原生js写ajax就像打电话 //打电话分下面4步//1.拿出手机//2.拨号//3.说话//4.挺对方说话 //ajax也分下面4步//1.创建ajax对象//2.连接到服务器//3.发送请求( ...

  3. PHP, Python, Node.js 哪个比较适合写爬虫?

    PHP, Python, Node.js 哪个比较适合写爬虫? 1.对页面的解析能力2.对数据库的操作能力(mysql)3.爬取效率4.代码量推荐语言时说明所需类库或者框架,谢谢.比如:python+ ...

  4. 用原生JavaScript写AJAX

    //原生js写ajax就像打电话 //打电话分下面4步//1.拿出手机//2.拨号//3.说话//4.听对方说话 //ajax也分下面4步//1.创建ajax对象//2.连接到服务器//3.发送请求( ...

  5. JS与APP原生控件交互

    "热更新"."热部署"相信对于混合式开发的童鞋一定不陌生,那么APP怎么避免每次升级都要在APP应用商店发布呢?这里就用到了混合式开发的概念,对于电商网站尤其显 ...

  6. PhoneGap或者Cordova框架下实现Html5中JS调用Android原生代码

    PhoneGap或者Cordova框架下实现Html5中JS调用Android原生代码 看看新闻网>看引擎>开源产品 0人收藏此文章, 发表于8小时前(2013-09-06 00:39) ...

  7. JS入门学习,写一个简单的图片库

    <!-- 新手刚开始学JS,每天坚持写点东西 坚持下去,希望能有所进步 .  加油~~ --> <!DOCTYPE html>                         ...

  8. JS里写入(混写)php asp

    原文:JS里写入(混写)php asp JS里写入(混写)php 方法1:<Br> <script language="javascript"> docum ...

  9. PHP原生写的生成图片缩略图类

    PHP原生写的生成图片缩略图类,本文以京东商品图片为例,分别生成三种不同尺寸的图片.调用方法很简单只要传参数高度和宽度,及新图片的名称. 引入缩略图类 include_once 'ImageResiz ...

随机推荐

  1. Linux shell脚本启动 停止 重启jar包

    最近做的微服务jar包想弄在持续集成中自动化部署,所以首先得有一个操作jar包的脚本 只需将jar文件的路径替换到APP_NAME的值就可以了,其他不用改 注意:window编辑的shell文件,通过 ...

  2. JENKINS针对不同项目组对用户进行权限分配

    权限需求 因JENKINS上存有de(开发).te(测试).re(预发布)等三个不同环境的项目,同时因为项目需求,需要对不同的开发及测试人员配置不同的jenkins权限,即以项目为单位,对不同人员进行 ...

  3. Groovy 设计模式 -- 组合模式

    Composite Pattern http://groovy-lang.org/design-patterns.html#_chain_of_responsibility_pattern 组合模式, ...

  4. 激活函数——tanh函数(理解)

    0 - 定义 $tanh$是双曲函数中的一个,$tanh()$为双曲正切.在数学中,双曲正切“$tanh$”是由基本双曲函数双曲正弦和双曲余弦推导而来. $$tanhx=\frac{sinhx}{co ...

  5. (三)Java工程化--Git起步

    GIT学习参考:https://git-scm.com/book/zh/v2 版本控制 版本控制记录了一个或若干文件的历史变化,便于今后查阅,恢复. 三类版本控制系统 本地版本控制系统 RCS : 本 ...

  6. BIO 和 NIO

    一.阻塞(Block)和非阻塞(NonBlock) 阻塞和非阻塞是进程在访问数据的时候,数据是否准备就绪的一种处理方式,当数据没有准备的时候阻塞: 阻塞:往往需要等待缞冲区中的数据准备好过后才处理其他 ...

  7. 51nod--1174 区间中最大的数 (RMQ)

    题目: 1174 区间中最大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出一个有N个数的序列,编号0 - N - 1.进行Q次查询,查询编号i至j ...

  8. [正则表达式]PCRE反向分组引用(语法)

    正则表达式中,凡出现圆括号(),括号中的匹配内容就会被认为是一个分组: 根据括号从左边出现的顺序命名分组代号,分组代号由1到n(代号0通常被一些语言用来引用整个表达式匹配的结果,即使这个表达式没有分组 ...

  9. 使用 ThreeSixty 创建可拖动的 360 度全景图片预览效果

    ThreeSixty 是生成可拖动的360度预览图像序列的 jQuery 插件.只需要在你的 HTML 页面包引入最新的 jQuery 和 threesixty.js 文件就可以使用了,支持键盘上的箭 ...

  10. KNN与K-Means的区别

    KNN(K-Nearest Neighbor)介绍 Wikipedia上的 KNN词条 中有一个比较经典的图如下: KNN的算法过程是是这样的: 从上图中我们可以看到,图中的数据集是良好的数据,即都打 ...