前端—Ajax基础

一、get和post请求报文的对比

get请求的请求报文详解

//--------------------------请求行--------------------------------
// GET  请求方式
// /qk/01.php?username=lw&password=123456    请求路径+参数
// HTTP/1.1 HTTP的版本号
GET /qk/01.php?username=lw&password=123456 HTTP/1.1

//--------------------------请求头--------------------------------
// Host:主机地址
Host: www.study.com
// HTTP1.1版本默认开启,建立过连接后,TCP连接不会断开,下次连接可以继续使用
Connection: keep-alive
//chrome浏览器自己增加的
Upgrade-Insecure-Requests: 1
//浏览器的代理字符串(版本信息)
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
//浏览器端可以接受的类型。
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,`*/*`;q=0.8
//从哪个页面发出的请求
Referer: http://www.study.com/qk/01-login.html
//检查浏览器支持的压缩方式
Accept-Encoding: gzip, deflate, sdch
//浏览器支持的语言,优先中文。
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6

//----------------------------请求体-------------------------------------
//get请求没有请求体,但是参数会拼接到请求行中

POST请求的请求报文

//-----------------------请求行---------------------------------------------
POST /qk/01.php HTTP/1.1

//-----------------------请求头--------------------------------------------
Host: www.study.com
Connection: keep-alive
//传递的参数的长度。
Content-Length: 29
Cache-Control: max-age=0
Origin: http://www.study.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
//内容类型:表单数据,如果是post请求,必须指定这个属性。
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,`*/*`;q=0.8
Referer: http://www.study.com/day02/01-login.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6

//------------------------请求体------------------------------------------
username=lw&password=123456

GET请求与POST请求的对比

  • GET请求没有请求体,因为GET请求的参数拼接到地址栏中了
  • POST请求有请求体,就是传递的参数
  • POST请求需要指定content-type属性。

响应与响应报文

//---------------------状态行(响应行)-------------------------------
//HTTP/1.1  HTTP版本
//200 响应的状态
	//200表示成功
	//404表示找不到资源
	//500表示服务端错误
HTTP/1.1 200 OK

//----------------------响应头-----------------------------------------------
Date: Thu, 22 Jun 2017 16:51:22 GMT
Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.4.45
X-Powered-By: PHP/5.4.45
Content-Length: 18
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
//内容类型,告诉浏览器该如何解析响应结果
Content-Type: text/html;charset=utf-8
//-----------------------响应体------------------------------------------------
用户登录成功

通常来说,我们不会用抓包工具来查看请求和响应,太麻烦了,可以直接使用谷歌浏览器来查看请求报文和响应报文。

谷歌浏览器会对报文进行一定的格式化,看起来虽然不是原生的报文,但是使用起来更加的方便简洁。

二、AJAX

即 Asynchronous [e’sɪŋkrənəs] Javascript And XML

本质是在HTTP协议的基础上以异步的方式与服务器进行通信。

同步与异步

同步和异步概念:

同步: 指的就是事情要一件一件做。等做完前一件才能做后一件任务

异步: 不受当前任务的影响,两件事情同时进行,做一件事情时,不影响另一件事情的进行。

编程中:异步程序代码执行时不会阻塞其它程序代码执行,从而提升整体执行效率。

网页异步应用:

  1. 验证用户名是否已经存在(一边输入,一边对比)。
  2. 百度搜索提示,及相关内容展示(关键字)。
  3. 异步加载。

XMLHttpRequest可以以异步方式的处理程序。

XMLHttpRequest

浏览器内建对象,用于与服务器通信(交换数据) , 由此我们便可实现对网页的部分更新,而不是刷新整个页面。这个请求是异步,即在往服务器发送请求时,并不会阻碍程序的运行,浏览器会继续渲染后续的结构。

发送get请求

XMLHttpRequest以异步的方式发送HTTP请求,因此在发送请求时,一样需要遵循HTTP协议。

//使用XMLHttpRequest发送get请求的步骤
//1. 创建一个XMLHttpRequest对象
var xhr = new XMLHttpRequest;//构造函数没有参数的情况,括号可以省略
//2. 设置请求行
//第一个参数:请求方式  get/post
//第二个参数:请求的地址 需要在url后面拼上参数列表
xhr.open("get", "08.php?name=lw");
//3. 设置请求头
//浏览器会给我们默认添加基本的请求头,get请求时无需设置
//4. 设置请求体
//get请求的请求体为空,因为参数列表拼接到url后面了
xhr.send(null);
  • get请求,设置请求行时,需要把参数列表拼接到url后面
  • get请求不用设置请求头
  • get请求的请求体为null

发送post请求

var xhr = new XMLHttpRequest;
//1. 设置请求行 post请求的参数列表在请求体中
xhr.open("post", "09.php");
//2. 设置请求头, post请求必须设置content-type,不然后端无法获取到数据
xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
//3. 设置请求体
xhr.send("name=lw&age=18");
  • post请求,设置请求行时,参数列表不能拼接到url后面
  • post必须设置请求头中的content-type为application/x-www-form-urlencoded
  • post请求需要将参数列表设置到请求体中.

获取响应

HTTP响应分为3个部分,状态行、响应头、响应体。

//给xhr注册一个onreadystatechange事件,当xhr的状态发生状态发生改变时,会触发这个事件。
xhr.onreadystatechange = function () {
  if(xhr.readyState == 4){
    //1. 获取状态行
    console.log("状态行:"+xhr.status);
    //2. 获取响应头
    console.log("所有的相应头:"+xhr.getAllResponseHeaders());
    console.log("指定相应头:"+xhr.getResponseHeader("content-type"));
    //3. 获取响应体
    console.log(xhr.responseText);
  }
}

readyState

readyState:记录了XMLHttpRequest对象的当前状态

//0:请求未初始化。
//1:请求已经建立,但是还没有开始发送。
//2:请求已发送,正在处理中
//3:请求在处理中;通常响应中已有部分数据可用了,但是服务器还没有完成响应的生成。
//4:响应已完成;您可以获取并使用服务器的响应了。(我们只需要关注状态4即可)

三、数据交互

浏览器端只是负责用户的交互和数据的收集以及展示,数据都是存储在服务器端。通过ajax的确可以返回一些简单的数据,但肯定会涉及到大量的复杂类型的数据传输,比如数组、对象等,每个编程语言的语法都不一样。因此采用通用的数据交换格式(XML、JSON)来进行数据的交互。

XML

什么是XML

  • XML 指可扩展标记语言(EXtensible Markup Language)
  • XML 是一种标记语言,很类似 HTML
  • XML 的设计宗旨是传输数据,而非显示数据
  • XML 标签没有被预定义。您需要自行定义标签。

语法规范

  • 必须有一个根元素(有且仅有一个)
  • 标签不可有空格、不可以数字或.开头、大小写敏感
  • 不可交叉嵌套,都是双标签,如果是单标签,必须闭合
  • 属性双引号(浏览器自动修正成双引号了)
  • 注释和HTML一样
<students>
    <student>
        <name>张三</name>
        <age>18</age>
        <gender></gender>
        <desc>路人甲</desc>
    </student>
    <student>
        <name>李四</name>
        <age>20</age>
        <gender></gender>
        <desc>路人乙</desc>
    </student>
</students>

php获取xml文件的内容

//注意,如果需要返回xml数据,需要把content-type改成text/xml,不然浏览器以text/html进行解析。
header('content-type:text/xml;charset=utf-8');
//用于获取文件的内容
//参数:文件的路径
$result = file_get_contents("data.xml");
echo $result;

html解析xml

//获取服务端返回的xml数据,需要使用xhr.responseXML,这是一个document对象,可以使用DOM中的方法查找元素。
var data = xhr.responseXML;
//获取所有的学生
var students = data.querySelectorAll("student");

缺点:虽然可以描述和传输复杂数据,但是其解析过于复杂并且体积较大,所以实现开发已经很少使用了。

JSON数据

JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript 规范的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。

  • 数据在名称/值对中
  • 数据由逗号分隔(最后一个健/值对不能带逗号)
  • 花括号保存对象,方括号保存数组
  • 键使用双引号
var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的
var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串
  • JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
  • 不同的语言各自也都对应有解析方法,需要解析完成后才能读取
  • JSON 和 JS 对象之间互转

json与js对象的相互转换

  • JS对象 ==> JSON字符串 JSON.stringify(obj)
    //obj是一个js对象
    var obj = {a: 'Hello', b: 'World'}
    //result就变成了一个json字符串了
    var result = JSON.stringify(obj);// '{"a": "Hello", "b": "World"}'
  • JSON字符串 ==> JS对象 JSON.parse(obj)
    //json是一个json字符串
    var json = '{"a": "Hello", "b": "World"}';
    //obj就变成了一个js对象
    var obj = JSON.parse(json);// {a: 'Hello', b: 'World'}

使用json进行数据传输

四、jQuery中的ajax方法

jQuery提供了更强大的Ajax封装

$.ajax

参数列表

参数名称描述取值示例
url后台地址url:“02.php”
type请求方式get/posttype:“get”
dataType服务器返回的数据格式json/xml/text,如果不指定,会自动根据content-type进行判定dataType:“json”
data发送的请求数据对象、字符串data:{name:“zs”, age:18}
beforeSend调用前的回调函数,在beforeSend中return false,会阻止ajax的发送function(){}beforeSend:function(){ }
success成功的回调函数function (data) {}success:function (data) {}
error失败的回调函数function (error) {}error:function(data) {}
complete完成后的回调函数function () {}complete:function () {}

使用示例:

$.ajax({
  type:"get",//请求类型
  url:"02.php",//请求地址
  data:{name:"zs", age:18},//请求数据
  dataType:"json",//希望接受的数据类型
  timeout:5000,//设置超时时间
  beforeSend:function () {
    //alert("发送前调用");
  },
  success:function (data) {
    //alert("成功时调用");
    console.log(data);
  },
  error:function (error) {
    //alert("失败时调用");
    console.log(error);
  },
  complete:function () {
    //alert("请求完成时调用");
  }
});

其他api(了解)

//$.post(url, [data], [callback], [dataType]);只发送post请求
//$.get(url, [data], [callback], [type]);//get请求

五、表单序列化 serialize

jquery提供了一个serialize()方法序列化表单,说白就是将表单中带有name属性的所有参数拼成一个格式为name=value&name1=value1这样的字符串。方便我们获取表单的数据。

//serialize将表单参数序列化成一个字符串。必须指定name属性
//name=cc&pass=123456&repass=123456&mobile=18511241111&code=1234
$('form').serialize();

jquery的ajax方法,data参数能够直接识别表单序列化的数据

$.post({
  url:"register.php",
  data:$('form').serialize(),
  dataType:'json',
  success:function (info) {
    console.log(info);
  }
});

六、模板引擎

是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。 数据+模版 = 最终需要显示的结构(动态)

常见的模板引擎

artTemplate是使用最广泛,效率最高的模板引擎,需要大家掌握。

artTemplate的使用

github地址

中文api地址

artTemplate入门

1.引入模板引擎的js文件

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

2.准备模板

<!--指定了type为text/html后,这一段script标签并不会当做js来解析-->

<script type="text/html" id="myTmp">
  <p>姓名:隔壁老王</p>
  <p>年龄:18</p>
  <p>技能:查水表</p>
  <p>描述:年轻力气壮</p>
</script>

3.准备数据

//3. 准备数据,数据是后台获取的,可以随时变化
var json = {
  userName:"隔壁老王",
  age:18,
  skill:"查水表",
  desc:"年轻气壮"
}

4.将模板与数据进行绑定

//第一个参数:模板的id
//第二个参数:数据
//返回值:根据模板生成的字符串。
var html = template("myTmp", json);
console.log(html);

5.修改模板

<script type="text/html" id="myTmp">
  <p>姓名:{{userName}}</p>
  <p>年龄:{{age}}</p>
  <p>技能:{{skill}}</p>
  <p>描述:{{desc}}</p>
</script>

6.将数据显示到页面

var div = document.querySelector("div");
div.innerHTML = html;

artTemplate标准语法

if语法

{{if gender='男'}}
  <div class="man">
{{else}}
  <div class="woman">
{{/if}}

each语法

<!--
  1. {{each data}}  可以通过$value 和 $index获取值和下标
  2. {{each data v i}}  自己指定值为v,下标为i
-->
{{each data v i}}
<li>
  <a href="{{v.url}}">
    <img src="{{v.src}}" alt="">
    <p>{{v.content}}</p>
   </a>
 </li>
{{/each}}
//如果返回的数据是个数组,可以使用对象进行包裹
var html = template("navTmp", {data:info});

七、同源与跨域

同源

同源策略的基本概念

所谓"同源"指的是"三个相同"。

协议相同   http  https
域名相同   www.baidu.com  www.taobao.cn  www.jd.com
端口相同   80 81 82

举例来说,http://www.example.com/dir/page.html这个网址,协议是http://,域名是www.example.com,端口是80(默认端口可以省略)。它的同源情况如下。

http://www.example.com/dir2/other.html:同源
http://example.com/dir/other.html:不同源(域名不同)
http://v2.www.example.com/dir/other.html:不同源(域名不同)
http://www.example.com:81/dir/other.html:不同源(端口不同)

同源策略的目的

同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。

因此同源策略是必须的,如果 cookie 可以在不同源的网站中共享,那么互联网将毫无安全可言。

同源策略的限制范围

随着互联网的发展,“同源策略”越来越严格,目前,如果非同源,以下三种行为都将收到限制。

1. Cookie、LocalStorage 和 IndexDB 无法读取。
2. DOM 无法获得。
3. AJAX 请求不能发送。

虽然这些限制是很有必要的,但是往往都会把服务器端架设到一台甚至是一个集群的服务器中,把客户端页面放到另外一个单独的服务器。两个不同源的网站之间可以相互请求数据的。这就需要使用到跨域

跨域

jsonp

JSONP(JSON with Padding)、可用于解决主流浏览器的跨域数据访问的问题。原理:服务端返回一个预先定义好的 javascript 函数的调用,并且将服务器的数据以该函数参数的形式传递过来,这个方法需要前后端配合。

jsonp: 带补丁的 json, 服务器不直接返回 json , 而是把json数据放到函数中作为实参传递

script 标签是不受同源策略的限制的,它可以载入任意地方的 JavaScript 文件,而并不要求同源。类似的还有imglink标签

<!--不受同源策略的标签-->
<img src="http://www.api.com/1.jpg" alt="" />
<link rel="stylesheet" href="http://www.api.com/1.css" />
<script src="http://www.api.com/1.js"></script>
jsonp 演化过程 1

php 文件

header("content-type:text/html;charset=utf-8");
echo "alert(1111)";

html 文件

<script src="http://www.api.com/testjs.php"></script>

原理:其实 src 的路径是什么文件不重要,无论引入 js 文件还是 php 文件,最后返回给浏览器的都是字符串,因此我们 script 标签是可以引入一个 php 文件的。

jsonp 演化过程 2

php 代码

header("content-type:text/html;charset=utf-8");
$arr = array(
    "name"=>"zs",
    "age"=>18
);
$result = json_encode($arr);
//这是一段js函数的调用的代码,$result就是我们想要的数据
echo "func($result)";

js 代码

<script>
  function func(data) {
    console.log(data);
  }
</script>
<script src="http://www.api.com/testjs.php"></script>

缺点:后端必须知道前端声明的方法的名字,后端才能调用。

jsonp 演化过程 3

php 代码

header("content-type:text/html;charset=utf-8");
$arr = array(
    "name"=>"zs",
    "age"=>18
);
$result = json_encode($arr);
//这是一段js函数的调用的代码,$result就是我们想要的数据
echo $_GET['callback']."($result)";

javascript 代码

function fun(data) {
  console.log(data);
}

var button = document.querySelector("button");
button.onclick = function () {
  var script = document.createElement("script");
  script.src = "http://www.api.com/testjs.php?callback=fun";
  document.body.appendChild(script);
};

jsonp 的原理就是 借助了 script 标签不受同源策略的限制,在服务端返回一个函数的调用,将数据作为当前调用函数的实参。 在浏览器端,需要程序要声明一个函数,通过形参就可以获取到服务端返回的对应的值。

jquery 对于 jsonp 的封装

// 使用起来相当的简单,跟普通的get请求没有任何的区别,只需要把dataType指定成jsonp即可。
$.ajax({
  type: "get",
  url: "http://www.api.com/testjs.php",
  dataType: "jsonp",
  data: {
    uname: "hucc",
    upass: "123456",
  },
  success: function (info) {
    console.log(info);
  },
});

XMLHttpRequest2.0

XMLHttpRequest 是一个 javascript 内置对象,使得 Javascript 可以进行异步的 HTTP 通信。

老版本的 XMLHttpRequest 的缺点:

//1. 仅支持传输文本数据,无法传说二进制文件,比如图片视频等。
//2. 受到了"同源策略"的限制
//3. 传输数据时,没有进度信息,只能提示完成与否。

新版本的功能:

1. 可以使用formData对象管理表单数据
2. 允许请求不同域名下的数据(跨域)
3. 支持上传二进制文件

跨域资源共享(CORS)

cors 的使用

新版本的 XMLHttpRequest 对象,可以向不同域名的服务器发出 HTTP 请求。这叫做"跨域资源共享"(Cross-origin resource sharing,简称 CORS)。

跨域资源共享(CORS)的前提

  • 浏览器支持这个功能
  • 服务器必须允许这种跨域。

服务器允许跨域的代码:

//允许所有的域名访问这个接口
header("Access-Control-Allow-Origin:*");

//允许www.study.com这个域名访问这个接口
header("Access-Control-Allow-Origin:http://www.study.com");

CORS 的具体流程

  1. 浏览器会向发送一条请求,服务器接受到请求之后,会返回请求头信息,浏览器查看返回的响应头信息中是否设置了header('Access-Control-Allow-Origin:请求源域名或者*');
  2. 如果没有设置,说明服务器不允许使用 cors 跨域,那么浏览器会把获取到的数据拦截。
  3. 如果返回的响应头中设置了header('Access-Control-Allow-Origin:请求源域名或者*');,浏览器会跟请求头中的Origin: http://www.study.com进行对比,如果满足要求,就把数据发送给用户。
  4. 结论:跨域行为是浏览器行为,是浏览器阻止了 ajax 行为。服务器与服务器之间是不存在跨域的问题的

jsonp 与 cors 的对比

  • jsonp 兼容性好,老版本浏览器也支持,但是 jsonp 仅支持 get 请求,发送的数据量有限。使用麻烦
  • cors 需要浏览器支持 cors 功能才行。但是使用简单,只要服务端设置允许跨域,对于客户端来说,跟普通的 get、post 请求并没有什么区别。
  • 跨域的安全性问题:因为跨域是需要服务端配合的 ,也就是说不论 jsonp 还是 cors,如果没有服务端的允许,浏览器是没法做到跨域的。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值