url地址
URL(全称是Uniform Resource Locator)中文叫统一资源定位符,用于标识互联网上每个资源的唯一存放位置。浏览器只有通过URL地址,才能正确定位资源的存放位置,从而成功访问到对应的资源。例如,www.baidu.com
url地址的组成部分
URL地址一般由三部组成:1. 客户端与服务器之间的通信协议 2. 存有该资源的服务器名称 3. 资源在服务器上具体的存放位置
get和post区别
get 方式
- 数据会拼接在 url 地址的后面?username=haha&password=123456
- 地址栏有长度限制,因此 get 方式提交数据大小不会超过 4k
post方式
- 数据不会在 url 中显示,相比 get 方式,post 更安全
- 提交的数据没有大小限制
根据 HTTP 规范,GET 用于信息获取,POST 表示可能修改变服务器上的资源的请求。
http协议
协议 是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规则或约定。通俗理解: 通信双方采用约定好的格式 来发送和接受消息(就是事先预定好的通信格式)。客户端和服务器之间要实现网页内容的传输, 则双方必须遵守网页内容的传输协议。网页内容又叫做超文本, 因此网页内容的传输协议又叫做超文本传输协议(Hypertext transfer protocol), 简称HTTP协议。HTTP协议规定了客户端与服务器之间进行的网页内容传输时, 所必须遵守的传输格式。
例如:
- 客户端要以HTTP协议要求的格式把数据提交到服务器
- 服务器要以HTTP协议要求的格式把内容响应到客户端
HTTP 协议分为请求 和响应 两个部分组成。
客户端发起的请求叫做HTTP请求, 客户端发送到服务器的消息, 叫做HTTP请求消息(又称请求报文)。
GET 请求与 POST 请求的对比:
- GET 请求没有请求体,因为 GET 请求的参数拼接到地址栏中了
- POST 请求有请求体,就是传递的参数
- POST 请求需要指定 content-type 属性。
查询字符串
查询字符串(URL 参数)是指在 URL 的末尾加上用于向服务器发送信息的字符串。它的格式是将英文的 ?
放在URL 的末尾,然后再加上 参数=值
,想加上多个参数的话,使用 &
符号进行分隔。以这个形式,可以将想要发送给服务器的数据添加到 URL 中。这种在 URL 地址后面拼接的参数,叫做查询字符串。
ajax
Ajax 的全称是 Asynchronous Javascript And XML(异步 JavaScript 和 XML), AJAX 不是一门的新的语言,而是对现有技术的综合利用。本质是在 HTTP 协议的基础上以异步的方式与服务器进行通信。
同步与异步
同步指的就是事情要一件一件做,等做完前一件才能做后一件任务。异步指的是不受当前任务的影响,两件事情同时进行,做一件事情时,不影响另一件事情的进行。在编程中,异步程序代码执行时不会阻塞其它程序代码执行,从而提升整体执行效率。
XMLHttpRequest 可以以异步方式的处理程序。
ajax的典型应用场景
- 用户名检测:注册用户时,通过 ajax 的形式,动态检测用户名是否被占用。
- 搜索提示:当输入搜索关键字时,通过 ajax 的形式,动态加载搜索提示列表。
- 数据分页显示:当点击页码值的时候,通过 ajax 的形式,根据页码值动态刷新表格的数据。
- 数据的增删改查:数据的添加、删除、修改、查询操作,都需要通过 ajax 的形式,来实现数据的交互。
XMLHttpRequest
XMLHttpRequest(简称 xhr)是浏览器提供的 Javascript 对象,通过它,用于与服务器通信(交换数据)。由此我们便可实现对网页的部分更新,而不是刷新整个页面。这个请求是异步,即在往服务器发送请求时,并不会阻碍程序的运行,浏览器会继续渲染后续的结构。最简单的用法 var xhrObj = new XMLHttpRequest()
发送get请求
使用XMLHttpRequest发送get请求的步骤:
- 创建一个XMLHttpRequest对象
- 调用 open 函数,指定 请求方式 与 URL地址(有参数的话, 就需要在url后面拼上参数列表)
- 调用 send 函数,发起 Ajax 请求
- 监听 xhr.onreadystatechange 事件
scss
//1. 创建一个XMLHttpRequest对象
var xhr = new XMLHttpRequest(); //构造函数没有参数的情况,括号可以省略
// 2. 调用 open 函数,指定 请求方式 与 URL地址(有参数的话, 就需要在url后面拼上参数列表)
// get 请求,设置请求行时,需要把参数列表拼接到 url 后面
xhr.open('GET', 'http://www.xxxxx.top:3006/api/getbooks')
// 3. 调用 send 函数,发起 Ajax 请求
xhr.send()
// 4. 监听 onreadystatechange 事件
xhr.onreadystatechange = function() {
// 4.1 监听 xhr 对象的请求状态 readyState ;与服务器响应的状态 status
if (xhr.readyState === 4 && xhr.status === 200) {
// 4.2 打印服务器响应回来的数据
console.log(xhr.responseText)
}
}
发送post请求
使用XMLHttpRequest发送get请求的步骤:
- 创建 xhr 对象
- 调用 xhr.open() 函数
- 设置 Content-Type 属性(固定写法)
- 调用 xhr.send() 函数,同时指定要发送的数据
- 监听 xhr.onreadystatechange 事件
javascript
// 1. 创建 xhr 对象
var xhr = new XMLHttpRequest();
// 2. 调用 open()
xhr.open('POST', 'http://www.xxxxx.top:3006/api/addbook');
// 3. 设置 Content-Type 属性(固定写法: post请求必须设置content-type)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 4. 调用 send(),同时将数据提交给服务器
xhr.send('bookname=水浒传&author=施耐庵&publisher=天津图书出版社');
// 5. 监听 onreadystatechange 事件
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText)
}
}
- post 请求, 参数列表不能拼接到 url 后面
- post 必须设置请求头中的 content-type 为 application/x-www-form-urlencoded
- post 请求需要将参数放到send中
获取响应
给xhr注册一个onreadystatechange事件,当xhr的状态发生状态发生改变时,会触发这个事件。
javascript
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记录了 XMLHttpRequest 对象的当前状态。
0:请求未初始化。XMLHttpRequest 对象已被创建,但尚未调用 open方法。
1:请求已经建立,但是还没有开始发送。
2:请求已发送,正在处理中。
3:请求在处理中;通常响应中已有部分数据可用了,但是服务器还没有完成响应的生成。
4:响应已完成;Ajax 请求完成,这意味着数据传输已经彻底完成或失败。(我们只需要关注状态4即可)
数据交互
浏览器端只是负责用户的交互和数据的收集以及展示,真正的数据都是存储在服务器端的。但是每个编程语言的语法都不一样。因此我们会采用通用的数据交换格式(XML、JSON)来进行数据的交互。简单理解就是数据交换格式,就是服务器端与客户端之间进行数据传输与交换的格式。
前端领域,经常提及的两种数据交换格式分别是 XML 和 JSON。其中 XML 用的非常少,所以,我们重点要学习的数据交换格式就是 JSON。
XML
XML 指可扩展标记语言(EXtensible Markup Language)。XML 是一种标记语言,很类似 HTML。它的设计宗旨是传输数据,而非显示数据。XML 标签没有被预定义,需要自行定义标签。
XML的语法规范是:
- 必须有一个根元素(有且仅有一个)
- 标签不可有空格、不可以数字或.开头、大小写敏感
- 不可交叉嵌套,都是双标签,如果是单标签,必须闭合
- 属性双引号(浏览器自动修正成双引号了)
- 注释和 HTML 一样
xml
<students>
<student>
<name>张三</name>
<age>18</age>
<gender>男</gender>
<desc>路人甲</desc>
</student>
<student>
<name>李四</name>
<age>20</age>
<gender>男</gender>
<desc>路人乙</desc>
</student>
</students>
XML虽然可以描述和传输复杂数据,但是格式臃肿,和数据无关的代码多,体积大,传输效率低。并且,在 Javascript 中解析 XML 比较麻烦。所以实现开发已经很少使用了。
JSON数据
JSON的英文全称是JavaScript Object Notation, 即 "JavaScript对象表示法"。简单来讲, JSON就是JavaScript对象和数组的字符串表示法, 使用文本表示一个JS对象或数组的信息, 因此, JSON的本质是字符串。JSON 是一种轻量级的文本数据交换格式,在作用上类似于 XML,专门用于存储和传输数据,但是 JSON 比 XML 更小、更快、更易解析。它 是在 2001 年开始被推广和使用的数据格式,到现今为止,JSON 已经成为了主流的数据交换格式。
JSON格式
- 数据在名称/值对中
- 数据由逗号分隔(最后一个健/值对不能带逗号)
- 花括号保存对象,方括号保存数组
- 键使用双引号
需要注意的是:
- 属性名必须使用双引号包裹
- 字符串类型的值必须使用双引号包裹(JSON 中不允许使用单引号表示字符串)
- JSON 中不能写注释
- JSON 的最外层必须是对象或数组格式
- 不能使用 undefined 或函数作为 JSON 的值
css
var obj = { a: "Hello", b: "World" }; // 这是一个对象,注意键名也是可以使用引号包裹的
var json = '{"a": "Hello", "b": "World"}'; // 这是一个 JSON 字符串,本质是一个字符串
JSON和js对象的关系
JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
css
//这是一个对象
var obj = {a: 'Hello', b: 'World'}
//这是一个 JSON 字符串,本质是一个字符串
var json = '{"a": "Hello", "b": "World"}'
JSON与js对象的相互转换
调用 JSON.stringify()
函数,把数据对象转换为json字符串的过程,叫做JSON序列化。
css
// JSON.stringify(obj) 实现 JS 对象 ==> JSON 字符串
// obj是一个js对象
var obj = { a: "Hello", b: "World" };
// result就变成了一个json字符串了
var result = JSON.stringify(obj); // '{"a": "Hello", "b": "World"}'
调用 JSON.parse()
,把json字符串转换为数据对象的过程, 叫做JSON反序列化。
css
// JSON.parse(obj) 实现 JSON 字符串 ==> JS 对象
// json是一个json字符串
var json = '{"a": "Hello", "b": "World"}';
// obj就变成了一个js对象
var obj = JSON.parse(json); // {a: 'Hello', b: 'World'}
axios
Axios 是专注于网络数据请求的库。相比于原生的 XMLHttpRequest 对象,axios 简单易用。相比于 jQuery中的ajax方法,axios 更加轻量化,只专注于网络数据请求。
axios发送get请求
axios.get('url', { params: { /参数/ } }).then(callback)
axios发送post请求
axios.post('url', { /参数/ }).then(callback)
javascript
// 调用 axios.post() 发起 POST 请求
axios.post(url, { location: '北京', address: '顺义' }).then(function(res) {
// res.data 是服务器返回的数据
var result = res.data
console.log(result)
})
直接使用axios发起请求
axios 也提供了类似于 jQuery 中 $.ajax() 的函数,语法如下:
php
axios({
method: '请求类型',
url: '请求的URL地址',
data: { /* POST数据 */ },
params: { /* GET参数 */ }
}) .then(callback)
同源与跨域
同源策略
1995 年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。 同源策略:最初,它的含义是指,A 网页不能往 B 网页发送 ajax 请求,除非这两个网页"同源"。所谓"同源"指的是"三个相同"。
- 协议相同 http https
- 域名相同 www.xxxA.com www.xxxB.cn www.xxxC.com
- 端口相同 80 81 82
如果两个页面的协议,域名和端口都相同,则两个页面具有相同的源。
举例来说,www.test.com/index.html 这个网址,协议是http://
,域名是www.example.com
,端口是80
(默认端口可以省略)。
www.test.com/other.html 同源(协议、域名、端口相同)
www.test.com/about.html 协议不同(http 与 https)
blog.test.com/movie.html 域名不同(www.test.com 与 blog.test.com)
www.test.com:7001/home.html 端口不同(默认的 80 端口与 7001 端口)
www.test.com:80/main.html 同源(协议、域名、端口相同)
同源策略的目的
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
设想这样一种情况:A 网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取 A 网站的 Cookie,会发生什么?
很显然,如果 Cookie 包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因此同源策略是必须的,如果 cookie 可以在不同源的网站中共享,那么互联网将毫无安全可言。
虽然这些限制是很有必要的,但是也给我们日常开发带来不好的影响。比如实际开发过程中,往往都会把服务器端架设到一台甚至是一个集群的服务器中,把客户端页面放到另外一个单独的服务器。那么这时候就会出现不同源的情况,如果我们知道两个网站都是安全的话,我们是希望两个不同源的网站之间可以相互请求数据的。这就需要使用到跨域 。
跨域
同源指的是两个 URL 的协议、域名、端口一致,反之,则是跨域。出现跨域的根本原因是浏览器的同源策略不允许非同源的 URL 之间进行资源的交互。
那么该如何解决跨域问题呢?
现如今,实现跨域数据请求,最主要的两种解决方案,分别是 JSONP
和 CORS
。
JSONP
JSONP(JSON with Padding)可用于解决主流浏览器的跨域数据访问的问题。它的原理是服务端返回一个预先定义好的 javascript 函数的调用,并且将服务器的数据以该函数参数的形式传递过来,这个方法需要前后端配合。
jsonp是带补丁的 json, 服务器不直接返回 json , 而是把 json 数据放到函数中作为实参传递。
script
标签是不受同源策略的限制的,它可以载入任意地方的 JavaScript 文件,而并不要求同源。类似的还有img
和link
标签。
xml
<!--不受同源策略的标签-->
<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 的原理就是 借助了 script 标签不受同源策略的限制,在服务端返回一个函数的调用,将数据作为当前调用函数的实参。 在浏览器端,需要程序要声明一个函数,通过形参就可以获取到服务端返回的对应的值。
CORS
新版本的 XMLHttpRequest 对象,可以向不同域名的服务器发出 HTTP 请求。这叫做跨域资源共享(Cross-origin resource sharing,简称 CORS)。
跨域资源共享(CORS)的前提是(1)浏览器支持这个功能;(2)服务器必须允许这种跨域。
服务器允许跨域的代码:
c
// 允许所有的域名访问这个接口
ctx.set('Access-Control-Allow-Origin', '*');
// 允许http://www.study.com这个域名访问这个接口
ctx.set('Access-Control-Allow-Origin', 'http://www.study.com');
具体流程
- 浏览器会向服务器发送一条请求,服务器接受到请求之后,会返回请求头信息,浏览器查看返回的响应头信息中是否设置了
header('Access-Control-Allow-Origin:请求源域名或者*');
- 如果没有设置,说明服务器不允许使用 cors 跨域,那么浏览器会把获取到的数据拦截。
- 如果返回的响应头中设置了
header('Access-Control-Allow-Origin:请求源域名或者*');
,浏览器会跟请求头中的Origin: http://www.study.com
进行对比,如果满足要求,就把数据发送给用户。
需要注意的是,跨域行为是浏览器行为,是浏览器阻止了 ajax 行为。服务器与服务器之间是不存在跨域的问题的。浏览器允许发起跨域请求,但是,跨域请求回来的数据,会被浏览器拦截,无法被页面获取到。
JSONP和CORS对比
jsonp:
- 兼容性好,老版本浏览器也支持
- 缺点是只支持 GET 请求,不支持 POST 请求。
- 发送的数据量有限。使用麻烦
CORS:
- 出现的较晚,它是 W3C 标准,属于跨域 Ajax 请求的根本解决方案。
- 支持 GET 和 POST 请求。
- 缺点是不兼容某些低版本的浏览器。(浏览器支持 cors 功能才行)
- 但是使用简单,只要服务端设置允许跨域,对于客户端来说,跟普通的 get、post 请求并没有什么区别。
跨域的安全性问题:很多人会觉得跨域能带来安全性问题,其实并不会,因为跨域是需要服务端配合的 ,也就是说不论 jsonp 还是 cors,如果没有服务端的允许,浏览器是没法做到跨域的。