URL地址
URL(Uniform Resource Locator)统一资源定位符
作用:标识互联网上每个资源的唯一存放位置
表单提交
方式:HTML中的<form>
标签,就是用于采集用户输入的信息,并通过<form>
标签的提交操作,把采集到的信息提交到服务器端进行处理
<form action='http://111.222.3.444:9999/get' method="GET">
<input type="text" name='name' value="admin"> <br>
<input type="password" name='pwd' value="123456"> <br>
<!-- 提交数据 -->
<input type="submit" value="提交-get">
</form>
<form action='http://111.222.3.444:9999/post' method="POST">
<input type="text" name='name' value="admin"> <br>
<input type="password" name='pwd' value="123456"> <br>
<!-- 提交数据 -->
<input type="submit" value="提交-post">
</form>
复制代码
表单的属性
action
- 指定表单的提交地址,默认值为当前页面的 URL 地址
- 当提交表单后,页面会立即跳转到 action 属性指定的 URL 地址
method
- 指定表单的提交方式,默认为get
- get/post
-
get:
-
数据会拼接在 url 地址的后面
?name=admin&pwd=123456
-
地址栏有长度限制,因此 get 方式提交数据大小不会超过 4k
-
GET 用于信息获取
-
-
post:
-
数据不会在 url 中显示,相比 get 方式,post 更安全
-
提交的数据没有大小限制
-
POST 表示可能修改服务器上的资源的请求
-
form
表单的注意点
input
的数据想要提交到后台,必须指定name
属性,后端通过name
属性获取值- 想要提交表单,不能使用
input:button
必须使用input:submit
HTTP协议
HTTP协议(Hypertext transfer protocol)超文本传输协议
作用:HTTP协议规定了客户端与服务器之间进行的网页内容传输时, 所必须遵守的传输格式
get 请求的请求报文详解
//--------------------------请求行--------------------------------
GET /day02/01.php?username=lw&password=123456 HTTP/1.1
// GET 请求方式
// /day02/01.php?username=lw&password=123456 请求路径+参数(注意点)
// HTTP/1.1 HTTP的版本号
//--------------------------请求头--------------------------------
// 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/day02/01-login.html
//检查浏览器支持的压缩方式
Accept-Encoding: gzip, deflate, sdch
//浏览器支持的语言,优先中文。
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
//----------------------------请求体-------------------------------------
// get请求没有请求体,但是参数会拼接到请求行中
复制代码
POST 请求的请求报文
//-----------------------请求行---------------------------------------------
POST /day02/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 200 OK
//HTTP/1.1 HTTP版本
//200 响应的状态
//200表示成功
//404表示找不到资源
//500表示服务端错误
//----------------------响应头-----------------------------------------------
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
ajax(Asynchronous Javascript And XML)异步JavaScript和XML
作用:在 HTTP 协议的基础上以异步的方式与服务器进行通信
传统的Ajax与JQuery ajax
传统 Ajax 指的是 XMLHttpRequest(XHR), 最早出现的发送后端请求技术,隶属于原始js中,核心使用XMLHttpRequest对象,多个请求之间如果有先后关系的话,就会出现回调地狱 (在异步js里,回调函数写的太多,回调套回调,代码繁琐)
JQuery ajax 是对原生XHR的封装,除此以外还增添了对JSONP的支持
ajax和form表单的对比
- 都能够发送http请求,ajax发送的是异步的http请求,表单发送的是同步的http请求
- 使用表单发送请求,页面一定会发生跳转;ajax允许你在操作页面的同时异步的发送请求,页面可以不跳转
传统的Ajax(XMLHttpRequest)
XMLHttpRequest(简称 xhr)是浏览器提供的 Javascript 对象,用于与服务器通信(交换数据)。
作用:实现对网页的部分更新,而不是刷新整个页面。这个请求是异步,即在往服务器发送请求时,并不会阻碍程序的运行,浏览器会继续渲染后续的结构。
最简单的用法
let xhr = new XMLHttpRequest()
发送 get 请求
使用XMLHttpRequest发送get请求的步骤:
-
创建 xhr 对象
let xhr = new XMLHttpRequest()
-
请求行 – 调用 xhr.open() 函数
xhr.open( ‘ get ’ , ' url地址 ?参数拼接的字符串 ' )
-
请求体 – 调用 xhr.send() 函数
xhr.send(null)
// 点击按钮准备
<button>发送请求 </button>
let btn = document.querySelector('button')
btn.onclick = function () { ... }
//1. 创建一个ajax对象, xhr 就是ajax实例, 可以发送请求
var xhr = new XMLHttpRequest();
// 2. 设置请求的三部分
// 2.1 设置请求行
// 参数1 :请求方式
// 参数2 : 请求url地址
xhr.open('get', 'http://111.222.3.444:9999/v1/get?name=admin&pwd=123456')
// 2.2 需要设置请求头
// get请求的请求头浏览器默认会添加, 此处不用设置请起头了
// 2.3 设置请求体 get请求没有请求体, 因为请求体就是放参数的, 参数已经拼在 url上了
// 注意:必须调用send才会发送请求,get请求,参数为null
// 参数:请求体
xhr.send()
复制代码
发送 post 请求
步骤:
-
创建 xhr 对象
let xhr = new XMLHttpRequest()
-
请求行 – 调用 xhr.open() 函数
xhr.open( ‘ post ’ , ' url地址 ' )
-
请求头 – 设置 Content-Type 属性(固定写法)
xhr.setRequestHeader( ' content-type ' , ' application/x-www-form-urlencoded ' )
-
请求体 – 调用 xhr.send() 函数,同时指定要发送的数据
xhr.send( 参数拼接的字符串 )
// 1. 创建 xhr
let xhr = new XMLHttpRequest()
// 2. 请求
// 2.1 请求行
xhr.open('post','http://111.222.3.444:9999/v1/post')
// 2.2 请求头
// Content-Type: application/x-www-form-urlencoded
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')
// 2.3 请求体
xhr.send('name=admin&pwd=123456')
复制代码
- post 请求, 参数列表不能拼接到 url 后面
- post 必须设置请求头中的 content-type 为 application/x-www-form-urlencoded
- post 请求需要将参数放到send中
获取响应
// 结构
<input type="text" class="name" placeholder="账号"> <br>
<input type="text" class="pwd" placeholder="密码"> <br>
<button>提交</button>
// 点击按钮准备
let btn = document.querySelector('button')
btn.onclick = function () { ... }
// 1. 收集数据
let name = document.querySelector('.name').value
let pwd = document.querySelector('.pwd').value
// 2. 发送ajax 请求
let xhr = new XMLHttpRequest()
xhr.open('get', `http://111.222.3.444:9999/v1/get?name=${name}&pwd=${pwd}`)
xhr.send()
// 3. 获取响应
xhr.onload = function () {
// console.log(xhr);
// console.log(xhr.status);
// console.log(xhr.responseText);
if (xhr.status === 200) {
alert(xhr.responseText)
} else {
alert('请求失败')
}
}
复制代码
jQuery 中的 ajax 方法
jQuery 中发起 Ajax 请求最常用的三个方法如下:
$.ajax
的参数列表
参数名称 | 描述 | 取值 | 示例 |
---|---|---|---|
url | 后台地址 | url:”02.php” | |
type | 请求方式 | get/post | type:”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 }, //请求数据
beforeSend: function() {
//alert("发送ajax前调用");
},
success: function(data) {
//alert("请求成功时调用");
console.log(data);
},
error: function(error) {
//alert("请求失败时调用");
console.log(error);
},
complete: function() {
//alert("请求完成时调用, 不论失败还是成功都会执行");
},
});
复制代码
$.ajax() 函数的基本语法:
$.ajax({
type: '', // 请求的方式,例如 GET 或 POST
url: '', // 请求的 URL 地址
data: { },// 这次请求要携带的数据
success: function(res) { } // 请求成功之后的回调函数
})
复制代码
通过JQuery ajax提交表单数据(★)
步骤:
-
监听表单提交事件
-
阻止表单默认提交行为
event.preventDefault()
,阻止表单的提交和页面的跳转 -
快速获取表单中的数据(表单序列化,JQ的方法)
$('form').serialize()
函数 或者$('form').serializeArray()
作用:
-
将表单中带有
name
属性的所有参数拼成一个格式为name=value&name1=value1
这样的查询字符串格式。方便我们获取表单的数据; -
jquery 的 ajax 方法的data 参数能够直接识别表单序列化的数据
-
-
清空全部(JQ的方法)
$('form')[0].reset()
<!--
1. 收集数据
2. 发送请求
-->
<form action="http://111.222.3.444:9999/v1/get">
<input type="text" name='bookname' placeholder="书名"> <br>
<input type="text" name='author' placeholder="作者"> <br>
<input type="text" name='publisher' placeholder="出版社"> <br>
<input type="submit" class="submit" value="提交">
</form>
<script src="https://juejin.cn/post/jquery.js"></script>
<script>
$('input[type=submit]').on('click', (e)=>{
//1. 替换 : 发送请求
//1. 阻止默认行为
e.preventDefault()
console.log('这里要发送请求了- $.ajax');
//2. 替换 : 获取数据
// 替换方式1 :
// let v1 = $('input[name=bookname]').val()
// let v2 = $('input[name=author]').val()
// let v3 = $('input[name=publisher]').val()
// console.log(v1,v2,v3);
// console.log(`bookname=${v1}&author=${v2}&publisher=${v3}`);
// 方式2 :
let res = $('form').serialize()
console.log(res);
//3. 清空
$('form')[0].reset()
})
</script>
复制代码
XMLHttpRequest Level2的新特性
设置 HTTP 请求的时限
- xhr版本
//1. 调试 network 里面的 Slow 3G,人为降低网速
//2. 调试接口
xhr.timeout = 1000; // 单位是ms
// 上面的语句,将最长等待时间设为 1000 毫秒。过了这个时限,就自动停止HTTP请求。
// 与之配套的还有一个 timeout 事件,用来指定回调函数:
xhr.ontimeout = function(event){
alert('请求超时!')
}
复制代码
- jquery版本
$.ajax({
url: 'http://111.222.3.444:9999/api/getbooks',
// 设置超时时间
timeout:1000,
success: function (res) {
console.log('res:', res);
},
error:function(err){
console.log('err:',err);// 超时
}
})
复制代码
通过FormData对象传输文件(★)
为了方便表单处理,HTML5 新增了一个 FormData 对象
作用有两个 ;
-
收集整个表单的数据 类似于
$('form').serialize()
(FormData 原生JS和JQ都能使用) -
上传文件
FormData对象管理表单数据
<form>
<input type="text" name="name"> <br>
<input type="text" name="pwd"> <br>
<button>按钮</button>
</form>
// 收集数据
//1. 拿到input, 再获取value
//2. serizlize() $('form').serialize()
//3. 使用 formdata
//1. 创建一个空的formdata
let fd = new FormData() // 这个是创建一个空的fd
fd.append('username','马哥')
fd.append('age',90)
fd.forEach((v,k) => {
console.log(v,k);
})
//2. 创建一个formdata, 放一个表单,这样的话,就直接把表单数据获取了
let fd = new FormData(document.querySelector('form'))
fd.forEach((v,k) => {
console.log(v,k);
})
复制代码
测试上传 fd 数据
<form>
<input type="text" name="name"> <br>
<input type="text" name="age"> <br>
<button>按钮</button>
</form>
// 创建 fd 并收集数据
let fd = new FormData(document.querySelector('form'))
let xhr = new XMLHttpRequest()
// 虽然这个接口特殊,但是能说明这样确实可以上传的
// 不需要设置请求头
xhr.open('post','http://111.222.3.444:9999/api/formdata')
xhr.send(fd)
xhr.onload = function () {
console.log(xhr.responseText);
}
复制代码
原生XHR上传文件-form+name
新版 XMLHttpRequest 对象,不仅可以发送文本信息,还可以上传文件。
<!-- 文件选择框 -->
<form>
<input type="file" name='avatar' />
</form>
复制代码
<style>
div {
width: 400px;
height: 400px;
border: 1px solid #000;
}
img {
width: 100%;
height: 100%;
}
</style>
<script>
// 需求:使用ajax上传图片
const input = document.querySelector('input')
const form = document.querySelector('form')
const div = document.querySelector('div')
// 让选择的文件发生了改变
input.onchange = function () {
console.log('哈哈哈')
// 发送ajax请求,上传图片
const xhr = new XMLHttpRequest()
xhr.open('post', 'http://111.222.3.444:9999/api/upload/avatar')
// 不能设置请求头
const fd = new FormData(form)
xhr.send(fd)
xhr.onload = function () {
console.log(xhr.responseText)
const res = JSON.parse(xhr.responseText)
div.innerHTML = `<img src="http://111.222.3.444:9999${res.url}">`
}
}
</script>
复制代码
原生XHR上传文件-input + append
// 收集图片数据 name='avatar'
let fd = new FormData()
fd.append('avatar',this.files[0])
xhr.send(fd)
复制代码
使用jQuery上传文件
<script>
$('input').on('change', function () {
const fd = new FormData()
fd.append('avatar', this.files[0])
$.ajax({
type: 'post',
url: 'http://www.111.222.3.444:9999/api/upload/avatar',
data: fd,
// 不修改 Content-Type 属性,使用 FormData 默认的 Content-Type 值
contentType: false,
// 不对 FormData 中的数据进行 url 编码,而是将 FormData 数据原样发送到服务器
processData: false,
success(res) {
console.log(res)
$('div').html(
`<img src="http://111.222.3.444:9999${res.url}">`
)
},
// 用于增强xhr,必须返回一个xhr对象
xhr() {
const xhr = new XMLHttpRequest()
xhr.upload.onprogress = function (e) {
$('progress').attr('max', e.total)
$('progress').attr('value', e.loaded)
}
return xhr
},
})
})
</script>
复制代码
文件上传进度条
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 300px;
height: 300px;
border: 1px solid #000;
}
img {
width: 100%;
}
</style>
</head>
<body>
<form>
<input type="file" name="avatar">
<div></div>
</form>
<!-- HTML中的<progress>元素用来显示一项任务的完成进度 -->
<progress value="" max="" hidden></progress>
<!-- max描述进度条的总工作量 -->
<!-- value描述进度条已完成的工作量 -->
<script>
let ipt=document.querySelector('input[type=file]')
let div=document.querySelector('div')
let progress=document.querySelector('progress')
ipt.onchange= function () {
progress.hidden=false
let fd=new FormData(document.querySelector('form'))
let xhr=new XMLHttpRequest()
xhr.open('post','http://111.222.3.444:9999/api/upload/avatar')
// 监听上传
xhr.upload.onprogress= function (e) {
// event.loaded 已传输的数据量
// event.total 总共的数据量
console.log(e.loaded,e.total);
progress.max=e.total
progress.value=e.loaded
}
xhr.upload.onload= function () {
progress.hidden=true
}
xhr.send(fd)
xhr.onload= function () {
console.log(xhr.responseText);
let res=JSON.parse(xhr.responseText)
div.innerHTML=`<img src="http://111.222.3.444:9999${res.url}">`
}
}
</script>
</body>
</html>
复制代码
Axios(★★★)
axios中文文档 www.axios-js.com/zh-cn/docs/
axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范。
特征:
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
请求配置
这些是创建请求时可以用的配置选项。只有 url
是必需的。如果没有指定 method
,请求将默认使用 get
方法
{
// (★)`url` 是用于请求的服务器 URL
url: '/user',
// (★)`method` 是创建请求时使用的方法
method: 'get', // default
// (★)`baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
// 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
baseURL: 'https://some-domain.com/api/',
// `transformRequest` 允许在向服务器发送前,修改请求数据
// 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
// 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
transformRequest: [function (data, headers) {
// 对 data 进行任意转换处理
return data;
}],
// `transformResponse` 在传递给 then/catch 前,允许修改响应数据
transformResponse: [function (data) {
// 对 data 进行任意转换处理
return data;
}],
// (★)`headers` 是即将被发送的自定义请求头
headers: {'X-Requested-With': 'XMLHttpRequest'},
// (★)`params` 是即将与请求一起发送的 URL 参数
// 必须是一个无格式对象(plain object)或 URLSearchParams 对象
params: {
ID: 12345
},
// `paramsSerializer` 是一个负责 `params` 序列化的函数
// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
paramsSerializer: function(params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
},
// (★★)`data` 是作为请求主体被发送的数据
// 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
// 在没有设置 `transformRequest` 时,必须是以下类型之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 浏览器专属:FormData, File, Blob
// - Node 专属: Stream
data: {
firstName: 'Fred'
},
// (★)`timeout` 指定请求超时的毫秒数(0 表示无超时时间)
// 如果请求话费了超过 `timeout` 的时间,请求将被中断
timeout: 1000,
// `withCredentials` 表示跨域请求时是否需要使用凭证
withCredentials: false, // default
// `adapter` 允许自定义处理请求,以使测试更轻松
// 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)).
adapter: function (config) {
/* ... */
},
// `auth` 表示应该使用 HTTP 基础验证,并提供凭据
// 这将设置一个 `Authorization` 头,覆写掉现有的任意使用 `headers` 设置的自定义 `Authorization`头
auth: {
username: 'janedoe',
password: 's00pers3cret'
},
// (★)`responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
responseType: 'json', // default
// `responseEncoding` indicates encoding to use for decoding responses
// Note: Ignored for `responseType` of 'stream' or client-side requests
responseEncoding: 'utf8', // default
// `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称
xsrfCookieName: 'XSRF-TOKEN', // default
// `xsrfHeaderName` is the name of the http header that carries the xsrf token value
xsrfHeaderName: 'X-XSRF-TOKEN', // default
// `onUploadProgress` 允许为上传处理进度事件
onUploadProgress: function (progressEvent) {
// Do whatever you want with the native progress event
},
// `onDownloadProgress` 允许为下载处理进度事件
onDownloadProgress: function (progressEvent) {
// 对原生进度事件的处理
},
// `maxContentLength` 定义允许的响应内容的最大尺寸
maxContentLength: 2000,
// `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte
validateStatus: function (status) {
return status >= 200 && status < 300; // default
},
// `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目
// 如果设置为0,将不会 follow 任何重定向
maxRedirects: 5, // default
// `socketPath` defines a UNIX Socket to be used in node.js.
// e.g. '/var/run/docker.sock' to send requests to the docker daemon.
// Only either `socketPath` or `proxy` can be specified.
// If both are specified, `socketPath` is used.
socketPath: null, // default
// `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项:
// `keepAlive` 默认没有启用
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
// 'proxy' 定义代理服务器的主机名称和端口
// `auth` 表示 HTTP 基础验证应当用于连接代理,并提供凭据
// 这将会设置一个 `Proxy-Authorization` 头,覆写掉已有的通过使用 `header` 设置的自定义 `Proxy-Authorization` 头。
proxy: {
host: '127.0.0.1',
port: 9000,
auth: {
username: 'mikeymike',
password: 'rapunz3l'
}
},
// `cancelToken` 指定用于取消请求的 cancel token
// (查看后面的 Cancellation 这节了解更多)
cancelToken: new CancelToken(function (cancel) {
})
}
复制代码
axios发起GET请求
axios.get(url,{
headers: {}, //headers携带自定义的请求头,如token
params : {} // axios.get一般将需要携带的参数拼接在url后面,也可以使用params
})
或者
axios.get(url?字符串,{
headers: {}
})
复制代码
代码演示
// axios.get(url,config)
// 方式一:拼接在url后面,以字符串形式
axios.get('http://111.222.3.444:9999/v1/get?name=admin&pwd=123456'
// 方式二:使用params,以键值对形式
axios.get('http://111.222.3.444:9999/v1/get', {
params: {
name: 'admin',
pwd: 123456
}
}).then(res => {
console.log('res', res);
})
复制代码
axios发起POST请求
axios.post( url , data , {
headers: {} //headers携带自定义的请求头,如token
})
// data为axios.get携带的参数(范围极为广泛,见上面),在请求前收集好
// params:{}在axios.post形式极为罕见,不使用
复制代码
代码演示
// 发表评论接口
// 第一种 : 参数是字符串
axios.post('http://111.222.3.444:9999/api/addcmt', 'username=aaaa&content=123').then(res => {
console.log('res', res);
})
// 第二种 : 参数是对象
axios.post('http://111.222.3.444:9999/api/addcmt', { username: 'admin', content: 123456 }).then(res => {
console.log('res', res);
})
复制代码
直接使用axios发起请求 (不建议使用)
axios({
method: '请求类型',
url: '请求的URL地址',
data: { /* POST数据 */ },
params: { /* GET参数 */ }
}) .then(callback)
复制代码
响应结构
某个请求的响应包含以下信息
{
// `data` 由服务器提供的响应
data: {},
// `status` 来自服务器响应的 HTTP 状态码
status: 200,
// `statusText` 来自服务器响应的 HTTP 状态信息
statusText: 'OK',
// `headers` 服务器响应的头
headers: {},
// `config` 是为请求提供的配置信息
config: {},
// 'request'
// `request` is the request that generated this response
// It is the last ClientRequest instance in node.js (in redirects)
// and an XMLHttpRequest instance the browser
request: {}
}
复制代码
使用 then
时,响应如下 :
axios.get('/user/12345')
.then(function(response) {
console.log(response.data);
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
})
简写为:
axios.get('/user/12345')
.then(res => {
console.log(res);
// res对象中的数据按需使用就行
})
复制代码
全局的 axios 默认值
// 默认的baseURL,配置后请求中的url可省略baseURL不写
axios.defaults.baseURL = 'https://api.example.com';
// 默认的headers,配置后请求中的headers可不写(由于有些请求没有header,一般使用条件语句来有选择的配置)
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// 默认的Content-Type,很少用
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
复制代码
拦截器
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
复制代码
同源和跨域
同源策略
同源的定义
同源的网站,有三个相同:协议、域名、端口
举例来说,http://www.test.com/index.html
这个网址,协议是http://
,域名是www.example.com
,端口是80
(默认端口可以省略)。
http协议默认端口80
,https默认端口443
http://www.test.com/other.html 同源(协议、域名、端口相同)
https://www.test.com/about.html 协议不同(http 与 https)
http://blog.test.com/movie.html 域名不同(www.test.com 与 blog.test.com)
http://www.test.com:7001/home.html 端口不同(默认的 80 端口与 7001 端口)
http://www.test.com:80/main.html 同源(协议、域名、端口相同)
复制代码
同源的目的
保证用户信息的安全,防止恶意的网站窃取数据
跨域
违反浏览器的同源策略就是跨域
跨域时浏览器的报文
- 允许跨域前
console控制台报错信息:
network情况:
- 允许跨域后
console控制台无报错
network情况正常:
解决跨域的方法(需要从后端入手)
JSONP(较少使用)
前提:script
标签是不受同源策略的限制的,它可以载入任意地方的 JavaScript 文件,而并不要求同源。类似的还有img
和link
标签
<!--不受同源策略的标签-->
<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>
复制代码
原理:借助了script
标签不受同源策略的限制,在服务端返回一个函数的调用,将数据作为当前调用函数的实参。 在浏览器端,需要程序要声明一个函数,通过形参就可以获取到服务端返回的对应的值。
注意点:JSONP只在get请求下有用
<script>
function success(res) {
console.log(res);
}
</script>
<script src="http://111.229.6.231:9996/v1/jsonp2?callback=success"></script>
复制代码
CORS(较常见)
CORS(Cross-Origin Resource Sharing)跨源资源共享
CORS 的具体流程(★)
- 浏览器会向发送一条请求,服务器接受到请求之后,会返回请求头信息,浏览器查看返回的响应头信息中是否设置了
header('Access-Control-Allow-Origin:请求源域名或者*');
- 如果没有设置,说明服务器不允许使用 cors 跨域,那么浏览器会把获取到的数据拦截。
- 如果返回的响应头中设置了
header('Access-Control-Allow-Origin:请求源域名或者*');
,浏览器会跟请求头中的Origin: http://www.study.com
进行对比,如果满足要求,就把数据发送给用户。 - 结论:跨域行为是浏览器行为,是浏览器阻止了 ajax 行为。服务器与服务器之间是不存在跨域的问题的
- 注意:浏览器允许发起跨域请求,但是,跨域请求回来的数据,会被浏览器拦截,无法被页面获取到!
详细见官方中文文档developer.mozilla.org/zh-CN/docs/…
jsonp 与 cors 的对比
-
jsonp 兼容性好,老版本浏览器也支持
-
缺点是只支持 GET 请求,不支持 POST 请求。
-
发送的数据量有限。使用麻烦
-
CORS:出现的较晚,它是 W3C 标准,属于跨域 Ajax 请求的根本解决方案。
- 支持 GET 和 POST 请求。
- 缺点是不兼容某些低版本的浏览器。(浏览器支持 cors 功能才行)
- 但是使用简单,只要服务端设置允许跨域,对于客户端来说,跟普通的 get、post 请求并没有什么区别。
-
跨域的安全性问题:跨域并不会带来安全性问题,因为跨域是需要服务端配合的 ,也就是说不论 jsonp 还是 cors,如果没有服务端的允许,浏览器是没法做到跨域的。
node中(后端)设置允许跨域:
方式一:
方式二:
反向代理
原理:服务器与服务器之间是不存在跨域的问题
如Nginx就是性能非常好的反向代理服务器,用来做负载均衡。
正向代理
反向代理
反向代理的实现:
①需要有一个负载均衡设备来分发用户请求,将用户请求分发到空闲的服务器上
②服务器返回自己的服务到负载均衡设备
③负载均衡将服务器的服务返回用户
正向代理和反向代理的区别:正向代理隐藏真实客户端,反向代理隐藏真实服务端