Ajax(Asynchronous JavaScript And XML)

通过ajax浏览器可以像服务器发送异步请求,最大的优势:可以在不刷新网页的情况下,异步的向后台发送请求,在前端接受并展示数据

本次学习所用到的插件

  1. Node.js
  2. NPM
  3. express(简单的web服务器)
  4. nodemon(用于自动重启node服务器)

XML

  1. XML是什么? 有什么用?

    1. XML 被设计用来传输和存储数据
    2. XML 的设计宗旨是传输数据(XML),而非显示数据(HTML)
    3. XML 被设计为具有自我描述性
    4. XML 标签没有被预定义。您需要自行定义标签
  2. 语法:

    <?xml version="1.0" encoding="utf-8">
    <root>
    <!-- 标签可以自由命名 -->
    <name>Fitz</name> <!-- 必须正确关闭标签 -->
    </root>
    <root>
    <!-- 属性必须加引号 -->
    <!-- 尽量不要使用属性 -->
    <name gender="male">Fitz</name>
    <address province="GD">HouJie</address>
    </root>
    <root>
    <!-- 这是错误的属性使用方法 -->
    <attr attr1="error" attr2="wrong">属性不应该这样用</attr>
    </root>
    <root>
    <!-- 特殊的符号应该使用实体 -->
    <sample>使用实体例如:大于号 &gt;</sample>
    </root>

JSON

由于JSON 比 XML 更小、更快,更易解析。所以现在AJAX返回的数据格式多是使用JSON

{
"name": "Fitz",
"hobby": "computer science",
"dream": "good at math"
}

关于AJAX

  1. ajax的优点

    1. 无需刷新页面即可与服务器进行通讯
    2. 允许根据用户事件来更新部分页面内容
  2. ajax的缺点
    1. 没有浏览历史,这就导致不能回退
    2. 存在跨域问题
    3. 对SEO不友好

HTTP协议

HTTP(hypertext transport protocol)超文本传输协议,规定了浏览器和万维网服务器之间互相通信的规则

  • 请求报文

    • 重要格式与参数
    行    ====>  GET/POST  /s?ie=utf-8  HTTP/1.1
    头 ====> Host: baidu.com
    Cookie: name=trash
    content-type: application/x-www-form-urlencoded
    user-Agent: chrome 83
    空行 ====>
    体 ====> username=root&password=root
  • 响应报文

  • 重要格式与参数

    行    ====>  HTTP/1.1  200  OK
    头 ====> Host: baidu.com
    content-type: text/html;charset=utf-8
    content-length: 2048
    空行 ====>
    体 ====> <html>
    <head></head>
    <body></body>
    </html>

AJAX重点之XMLHttpRequest对象

XMLHttpRequest对象作用是前端向服务端发送ajax请求,别接收来自服务端的数据

``` javascript {.line-numbers}
//主要步骤 // 1 创建xhr对象
var xhr = new XMLHttpRequest(); // 2 初始化 设置请求方法 与 URL
xhr.open('GET','http://127.0.0.1:8000/server'); // 3 发送请求
xhr.send(); // 4 事件绑定 处理服务端返回的结果
xhr.onreadystatechange = function(){
if (xhr.readyState === 4){
if (xhr.status >= 200 && xhr.status < 300){
//处理结果
// console.log(`行 状态码===>${xhr.status}`);
// console.log(`行 状态字符串===>${xhr.statusText}`);
// console.log(`头===>${xhr.getAllResponseHeaders()}`);
// console.log(`体===>${xhr.response}`);
}else{
console.log('Some Error !');
}
}
```

关于 onreadystatechange与readyState

每当 readyState 改变时,就会触发 onreadystatechange 事件,readyState存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。

0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪

服务端 实例

使用插件 express

//引入express
const express = require("express"); //创建应用对象
const app = express(); //创建路由规则
app.get('/server',(request,response)=>{
//request 请求报文封装
//response 响应报文封装 //设置响应头
//允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
response.send('成功接收到来自服务端的消息');
}) app.post('/server',(request,response)=>{
//request 请求报文封装
//response 响应报文封装 //设置响应头
//允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
response.send('成功接收到来自服务端的消息 -post method');
}) app.listen(8000,()=>{
console.log('服务已经在8000端口启动....');
})

ajax-get 实例

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewpor" content="width=device-width initial-scale=1.0">
<title>Fitz</title> <style> * {
margin: 0;
padding: 0;
} #result{
width: 200px;
height: 100px;
border: solid 1px black;
} </style> </head>
<body>
<button>点击发送请求</button>
<div id="result"></div> <script>
//获取button
var btn = document.getElementsByTagName('button')[0];
var result = document.getElementById("result");
btn.onclick = function(){
//AJAX步骤 // 1 创建xhr对象
var xhr = new XMLHttpRequest();
// 2 初始化 设置请求方法 与 URL
xhr.open('GET','http://127.0.0.1:8000/server?name=fitz');
// 3 发送请求
xhr.send();
// 4 事件绑定 处理服务端返回的结果
xhr.onreadystatechange = function(){
if (xhr.readyState === 4){
if (xhr.status >= 200 && xhr.status < 300){
//处理结果
// console.log(`行 状态码===>${xhr.status}`);
// console.log(`行 状态字符串===>${xhr.statusText}`);
// console.log(`头===>${xhr.getAllResponseHeaders()}`);
// console.log(`体===>${xhr.response}`); //展示在前端div中
result.innerHTML = xhr.response;
}else{
console.log('Some Error !');
}
}
}
}
</script>
</body>
</html>

ajax-post 实例

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewpor" content="width=device-width initial-scale=1.0">
<title>Fitz</title> <style> * {
margin: 0;
padding: 0;
} #result{
width: 200px;
height: 100px;
border: solid 1px black;
} </style> </head>
<body>
<button>点击发送请求</button>
<div id="result"></div> <script>
//获取button
var btn = document.getElementsByTagName('button')[0];
var result = document.getElementById("result");
btn.onclick = function(){
//AJAX步骤 // 1 创建xhr对象
var xhr = new XMLHttpRequest();
// 2 初始化 设置请求方法 与 URL
xhr.open('POST','http://127.0.0.1:8000/server');
// 3 发送请求
xhr.send('name=Fitz&gender=Male'); //post请求参数应在send方法中添加
// 4 事件绑定 处理服务端返回的结果
xhr.onreadystatechange = function(){
if (xhr.readyState === 4){
if (xhr.status >= 200 && xhr.status < 300){
//处理结果
// console.log(`行 状态码===>${xhr.status}`);
// console.log(`行 状态字符串===>${xhr.statusText}`);
// console.log(`头===>${xhr.getAllResponseHeaders()}`);
// console.log(`体===>${xhr.response}`); //展示在前端div中
result.innerHTML = xhr.response;
}else{
console.log('Some Error !');
}
}
}
}
</script>
</body>
</html>

设置请求头信息

// 2  初始化   设置请求方法 与 URL
xhr.open('POST','http://127.0.0.1:8000/server');
//设置请求头
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
// 3 发送请求
xhr.send('name=Fitz&gender=Male');

服务端响应JSON数据

方法一

前端代码

var div = document.getElementById('result');
window.onkeydown = function(){
//发送请求
var xhr = new XMLHttpRequest();
xhr.open('GET','http://127.0.0.1:8000/server');
xhr.send();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4){
if (xhr.status >= 200 && xhr.status < 300){
//方法一
//通过手动转换来响应JSON
let data = JSON.parse(xhr.response);
console.log(data);
div.innerHTML = data.username;
}
}
}
}

方法二

前端代码

var div = document.getElementById('result');
window.onkeydown = function(){
//发送请求
var xhr = new XMLHttpRequest();
xhr.open('GET','http://127.0.0.1:8000/server');
xhr.send();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4){
if (xhr.status >= 200 && xhr.status < 300){
//方法二
//自动转换
console.log(xhr.response);
div.innerHTML = xhr.response.username;
}
}
}
}

后端代码

//引入express
const express = require("express");
const { json } = require("body-parser"); //创建应用对象
const app = express(); // //创建路由规则
app.all('/server',(request,response)=>{
//request 请求报文封装
//response 响应报文封装 //设置响应头
//允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
response.setHeader('Access-Control-Allow-Header','*') //要发送回去前端的数据
const data = {
username: 'root',
password: 'root123'
} const data2str = JSON.stringify(data); //手动将data对象转换为JSON字符串
response.send(data2str); //send方法只能接收一个字符串
}) app.listen(8000,()=>{
console.log('服务已经在8000端口启动....');
})

AJAX关于在IE中的缓存问题

解决方法:使用时间戳以保证每次的URL都不一样(参数不一样)

var xhr = new XMLHttpRequest();
xhr.open("GET",'http://127.0.0.1:8000/ie?t'+Date.now()); //使用时间戳
xhr.send();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4){
if (xhr.status >= 200 && xhr.status < 300){
div.innerHTML = xhr.response; //把结果在前端显示
}
}
}

超时设置、回调与网络异常的回调

var xhr = new XMLHttpRequest();
//设置超时
xhr.timeout = 2000;
//设置超时回调
xhr.ontimeout = function(){
console.log('你的网络似乎有些慢');
}
//设置断网回调
xhr.onerror = function(){
console.log('你的网络似乎有些问题');
}
xhr.open("GET",'http://127.0.0.1:8000/cancel); //使用时间戳
xhr.send();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4){
if (xhr.status >= 200 && xhr.status < 300){
div.innerHTML = xhr.response; //把结果在前端显示
}
}
}

取消ajax请求

var btn = document.getElementById('btn');
var btn2 = document.getElementById('btn2');
var div = document.getElementById('result'); var xhr = null; addEventListener('click',function(){
if(xhr){
xhr.abort();
}
xhr = new XMLHttpRequest();
xhr.open("GET",'http://127.0.0.1:8000/cancel');
xhr.send();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4){
if (xhr.status >= 200 && xhr.status < 300){
div.innerHTML = xhr.response; //把结果在前端显示
}
}
}
}) btn2.onclick = function(){
xhr.abort();
}

jquery发送ajax请求

$(function(){
//get
$('button').eq(0).click(function(){
$.get('http://127.0.0.1:8000/jquery',
{
name: 'fitz',
age: 20
},
function(data){
console.log(data);
},'json')
}) //post
$('button').eq(1).click(function(){
$.post('http://127.0.0.1:8000/jquery',
{
name: 'fitz',
age: 20
},
function(data){
console.log(data);
})
}) //通用方法
$('button').eq(2).click(function(){
$.ajax({
//url
url: 'http://127.0.0.1:8000/jquery',
//要发送的参数
data: {
a: 'a',
b: 'b'
},
//ajax请求类型
type: 'GET',
//指定响应体的类型
dataType: 'json',
//设置超时时间
timeout: 2000,
//成功的回调
success: function(data){
console.log(data);
},
//失败的回调
error: function(e){
console.log(e);
},
//设置头部信息
headers: {
a: 200
}
})
})

fetch函数发送ajax请求

fetch('http://127.0.0.1:8000/fetch?test=ok',
{
//请求方法
method: 'POST',
//请求头
headers: {
name: 'Da'
},
//请求体
body: 'username=tri4123'
}).then((response)=>{
console.log(response);
return response.text();
//可以自动解析响应体为JSON格式的数据
// return response.json();
}).then((response=>{
console.log(response);
})
);

跨域

同源策略:协议、域名、端口号 必须完全相同

违背同源策略的称之为跨域

解决跨域

使用具备跨域特性的标签:<img> <script> <link> <iframe>

  1. 使用jsonp:在前段定义处理函数,供后端调用

    前端代码

    //在前段设置处理函数,供后端调用
    <script>
    //处理数据的函数
    function handleData(data){
    //获取result元素
    var result = document.getElementById('result');
    result.innerHTML = data.name;
    }
    </script> <!-- <script src="./jsonp.js"></script> -->
    <script src="http://127.0.0.1:8000/jsonp-server"></script>

    后端代码

    const express = require("express");
    const app = express();
    app.all('/jsonp-server',(request,response)=>{
    var PersonInfo = {
    name: 'Lx'
    } //调用前端已经定义好的函数
    //就能将后端数据跨域传给前端
    response.end(`handleData(${JSON.stringify(PersonInfo)})`)
    // response.send('console.log("jsonp实验成功")')
    })
  2. jquery(原理还是jsonp)

    前端代码


    //callback=? 参数是必须的,这会在前端注册一个函数 供后端调用
    $.getJSON('http://127.0.0.1:8000/server?callback=?',function(){
    //后端的数据....
    })

    后端代码

    const express = require("express");
    const app = express();
    app.all('/server',(request,response)=>{
    var PersonInfo = {
    name: 'Lx'
    } //获取在前端注册的callback函数
    var callbackFunc = request.query.callback; //调用前端已经定义好的函数
    //就能将后端数据跨域传给前端
    response.end(`${callbackFunc}(${JSON.stringify(PersonInfo)})`);
    })
  3. CORS 跨域资源共享 官方的跨域方案

CORS通过在服务端设置一个响应头告诉前端,该请求是否允许跨域,浏览器收到响应头后会对响应进行放行

后端代码

//允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
response.setHeader('Access-Control-Allow-Headers','*');
response.setHeader('Access-Control-Allow-Methods','*');

看完我的笔记不懂也会懂----Ajax的更多相关文章

  1. 看完我的笔记不懂也会懂----bootstrap

    目录 Bootstrap笔记 知识点扫盲 容器 栅格系统 源码分析部分 外部容器 栅格系统(盒模型)设计的精妙之处 Bootstrap笔记 写在开始: 由于我对AngulaJS的学习只是一个最浅显的过 ...

  2. 看完我的笔记不懂也会懂----AngulaJS

    目录 Angular.js学习笔记 ng-app(指令) ng-model ng-init angular之表达式 双向数据绑定 数据流向的总结 作用域对象 控制器对象 依赖对象与依赖注入 命令式与声 ...

  3. 看完我的笔记不懂也会懂----git

    Git学习笔记 - 什么是Git - 首次使用Git - DOS常用命令 - Git常用命令 - 关于HEAD - 版本回退 - 工作区.暂存区与版本库 - git追踪的是修改而非文件本身 - 撤销修 ...

  4. 看完我的笔记不懂也会懂----Node.js

    Node.js 学习 - 命令行窗口 - 进程与线程 - ECMAScript的缺点 - Node模块化 - Node中的全局对象 - 包 package - NPM包管理器 (Node Packag ...

  5. 看完我的笔记不懂也会懂----javascript模块化

    JavaScript模块化 模块化引子 模块化的历史进化 模块化规范 CommonJS规范 Node.js(服务器端) 下项目的结构分析 browerify(浏览器端) 下项目的结构分析 AMD规范 ...

  6. 看完我的笔记不懂也会懂----less

    目录 Less学习 语法篇 注释 变量 映射(Maps) @规则嵌套和冒泡 less中的嵌套规则 less中的混合 less的运算 extend延伸/继承 less忽略编译(转义) 导入(Import ...

  7. 看完我的笔记不懂也会懂----MongoDB

    MongoDb数据库学习 - 数据库的分类 - 数据库基本概念 - MongoDB常用指令 - MongoDB的CURD - sort({key:*[1,-1]}).limit(num).skip(n ...

  8. 看完我的笔记不懂也会懂----MarkDown使用指南

    目录 语法 [TOC] 自动生成目录 1. 标题 2. 文本强调 3. 列表 4. 图片 5. 超链接 6. 文本引用 7. 分割线 8. 代码 9. 任务列表 (MPE专属) 10. 表格 11. ...

  9. 看完我的笔记不懂也会懂----ECMAscript 567

    目录 ECMAscript 567 严格模式 字符串扩展 数值的扩展 Object对象方法扩展 数组的扩展 数组方法的扩展 bind.call.apply用法详解 let const 变量的解构赋值 ...

随机推荐

  1. CF-1354 E. Graph Coloring(二分图,背包,背包方案输出)

    E. Graph Coloring 链接 n个点m条边的无向图,不保证联通,给每个点标号1,2,3.1号点个数n1,2号点个数n2,3号点个数n3.且每条边的两点,标号之差绝对值为1.如果有合法方案, ...

  2. 【uva 11572】Unique Snowflakes(算法效率--滑动窗口,3种实现方法)

    题意:求长度为N的序列中,最长的一个无重复元素的连续子序列. 解法:[L,R]每次R++或L++延伸就可以得到答案. 实现:(1)next[],last[]--O(n): 1 #include< ...

  3. 牛客练习赛70 B.拼凑 (序列自动机)

    题意:有一个模板串,有\(T\)个字符串,从字符串中找到某个子串,使得这个子串中的子序列包含模板串,求最短的子串的长度. 题解:找子序列,很容易想到序列自动机,根据序列自动机的原理,我们一定可以确保除 ...

  4. Educational Codeforces Round 89 (Rated for Div. 2) C. Palindromic Paths (思维)

    题意:有一个\(n\)x\(m\)的矩阵,从\((1,1)\)出发走到\((n,m)\),问最少修改多少个数,使得所有路径上的数对应相等(e.g:\((1,2)\)和\((n-1,m)\)或\((2, ...

  5. 3.安装可视化工具kibana

    作者 微信:tangy8080 电子邮箱:914661180@qq.com 更新时间:2019-06-19 10:10:42 星期三 欢迎您订阅和分享我的订阅号,订阅号内会不定期分享一些我自己学习过程 ...

  6. canvas实现简易时钟效果

    代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8& ...

  7. POJ 2778 DNA Sequence(AC自动机 + 矩阵快速幂)题解

    题意:给出m个模式串,要求你构造长度为n(n <= 2000000000)的主串,主串不包含模式串,问这样的主串有几个 思路:因为要不包含模式串,显然又是ac自动机.因为n很大,所以用dp不太好 ...

  8. python文件持久化存储

    文件持久化存储 目录 文件持久化存储 脑图 文件的操作 with 语句 OS模块 json模块 存储为Excel文件 脑图 文件的操作 import os import platform # 1. 获 ...

  9. CSS hover box

    CSS hover box transition 踩坑指南, display: none; 作为初始状态,不会产生动画效果,必须设置 height: 0; 或 width: 0; 来实现隐藏! tra ...

  10. How to enable HTTPS for local development in macOS using Chrome

    How to enable HTTPS for local development in macOS using Chrome HTTPS, macOS, Chrome local HTTPS htt ...