前端数据请求方式总结前端数据请求方式,原生JS发送请求,-axios,-jQuery-AJAX,同源策略,跨域
前端数据请求方式总结(前端数据请求方式,原生JS发送请求, axios, jQuery AJAX,同源策略,跨域)
前端数据请求方式总结
1. 前端数据请求方式
发请求方式 | 请求方法 | 缺陷 |
---|---|---|
form | GET、POST | 刷新页面或新开页面 |
a | GET | 刷新页面或新开页面 |
img | GET | 以图片展示,需要加载一张图片 |
link | GET | 以CSS、favicon形式展示 |
script | GET | 只能以JS脚本运行,JSONP原理 |
<form>
使用 form 表单的action
向指定 url 发请求,会刷新页面或新开页面。<a>
使用<a>
标签的href
属性发__GET__请求,会刷新页面或新开页面。<img>
使用<img>
标签的src
属性发__GET__请求,只能以图片形式展示。<link>
使用<link>
标签的href
属性发__GET__请求,只能以CSS、favicon 的形式展示<script>
使用<script>
标签的src
属性发__GET__请求,只能以脚本形式运行,JSONP
2. 原生JS发送请求
2.1 XMLHttpRequest 对象
重点: XMLHttpRequest 对象用来在浏览器和服务器之间进行数据传输
使用 XMLHttpRequest 对象,首先需要生成一个实例。
let request = new XMLHttpRequest();
1. request.open(method,url,async)用来开启数据传输通路
三个参数分别对应:
- method:请求的方法,可以是GET、PPST、PUT、DELETE等
- url:请求的路径
- async:是否异步,默认为true,就是异步。false 为同步,可能造成浏览器阻塞。
2. request.send()
request.send()用来向请求路径发送数据。当请求有数据发送时,参数为所发送的数据。
同步请求会等全部响应完毕再返回,异步请求直接返回该方法。
3. readyState属性
readyState属性返回一个 XMLHttpRequest 代理当前所处的状态。
值 | 状态 | 描述 |
---|---|---|
0 | UNSENT | 代理被创建,但尚未调用 open() 方法。 |
1 | OPENED | open() 方法已经被调用。 |
2 | HEADERS_RECEIVED | send() 方法已经被调用,并且头部和状态已经可获得。 |
3 | LOADING | 下载中; responseText 属性已经包含部分数据。 |
4 | DONE | 下载操作已完成。 |
4. onreadystatechange属性
onreadystatechange属性监听 readyState 的值(监听 XMLHttpRequest代理的状态),当值发生变化(状态变化),对不同的状态执行相应的回调函数。
以上4个方法/属性就可以完成一个AJAX的请求
5. request.setRequestHeader()方法
request.setRequestHeader()方法:在发送请求之前设置请求头,对应http请求的第二部分。
request.setRequestHeader('Content-Type','x-www-form-urlencoded')
6. request.responseText 属性
request.responseText 属性就是 AJAX 中后端返回的数据,一般是 JSON 格式的字符串。
2.2 使用xhr发起GET请求
步骤:
- 创建 xhr 对象
- 调用 xhr.open() 函数
- 调用 xhr.send() 函数
- 监听 xhr.onreadystatechange 事件
<script>
// 1. 创建 xhr 对象
const xhr = new XMLHttpRequest();
// console.log(xhr);
// 2.监听 xhr.onreadystatechange 事件
xhr.addEventListener('load', function () {
// 监听 xhr 对象的请求状态 readyState ;与服务器响应的状态 status
if (xhr.status === 200) {
//打印服务器响应回来的数据
console.log(xhr.responseText);
}
});
// 3.调用 xhr.open() 函数
xhr.open('get', 'http://www.liulongbin.top:3006/api/getbooks?id=1');
// 4.调用 xhr.send() 函数
xhr.send();
</script>
2.3 使用xhr发起POST请求
步骤:
- 创建 xhr 对象
- 调用 xhr.open() 函数
- 设置 Content-Type 属性(固定写法)
- 调用 xhr.send() 函数,同时指定要发送的数据
- 监听 xhr.onreadystatechange 事件
// 1. 创建 xhr 对象
var xhr = new XMLHttpRequest()
// 2. 调用 open()
xhr.open('POST', 'http://www.liulongbin.top:3006/api/addbook')
// 3. 设置 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)
}
}
2.4 封装自己的Ajax函数
<script>
// 封装自己的Ajax函数
// data对象:我们需要把data函数中的对象 转化为字符串对象,从而提交给服务器 因此我们要resloveData函数:
// resloveData()思路先定义一个数组 ;然后循环数组data中的元素,并将元素通过push方法将键值对压进我们新定义的数组中;循环结束后将元素用户&连接
function resolveData(data) {
let arr = [];
for (let k in data) {
arr.push(k + '=' + data[k]);
console.log(k + '=' + data[k]);
}
return arr.join('&');
}
var test = resolveData({ name: '张三', age: 18 });
console.log(test);
function myAjax(optins) {
const xhr = new XMLHttpRequest();
// 调用resolveData()函数并指定一个变量来接收拼接好的字符串
const val = resolveData(optins.data);
// xhr添加监听事件然后获取附属器上的数据
xhr.onreadystatechange = function () {
if (xhr.readyState == 400 && xhr.status == 200) {
var res = JSON.parse(xhr.responseText);
options.success(result);
// 判断请求的类型
if (options.method.toUpperCase() == 'GET') {
// 发起get请求
xhr.open('GET', 'optioms.URL?s');
xhr.send();
} else if (options.method.toUpperCase() == 'POST') {
// 发起post请求
xhr.send('POST', 'options.URL');
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send(val);
}
}
};
}
</script>
3. axios
3.1 axios发起GET请求
axios.get('url', { params: { /*参数*/ } }).then(callback)
具体的请求示例如下:
// 请求的 URL 地址
var url = 'http://www.liulongbin.top:3006/api/get'
// 请求的参数对象
var paramsObj = { name: 'zs', age: 20 }
// 调用 axios.get() 发起 GET 请求
axios.get(url, { params: paramsObj }).then(function(res) {
// res.data 是服务器返回的数据
var result = res.data
console.log(res)
})
3.2 axios发起POST请求
axios.post('url', { /*参数*/ }).then(callback)
具体的请求示例如下:
// 请求的 URL 地址
var url = 'http://www.liulongbin.top:3006/api/post'
// 要提交到服务器的数据
var dataObj = { location: '北京', address: '顺义' }
// 调用 axios.post() 发起 POST 请求
axios.post(url, dataObj).then(function(res) {
// res.data 是服务器返回的数据
var result = res.data
console.log(result)
})
3.3 直接使用axios发起请求
axios 也提供了类似于 jQuery 中 $.ajax() 的函数,语法如下:
axios({
method: '请求类型',
url: '请求的URL地址',
data: { /* POST数据 */ },
params: { /* GET参数 */ }
}) .then(callback)
1. 直接使用axios发起GET请求
axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/get',
params: { // GET 参数要通过 params 属性提供
name: 'zs',
age: 20
}
}).then(function(res) {
console.log(res.data)
})
2. 直接使用axios发起POST请求
axios({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/post',
data: { // POST 数据要通过 data 属性提供
bookname: '程序员的自我修养',
price: 666
}
}).then(function(res) {
console.log(res.data)
})
4. jQuery AJAX
4.1 jQuery AJAX发起GET请求
<!DOCTYPE html>
<html>
<head>
<script src="/jquery/jquery-1.11.1.min.js"></script>
<script>
$(document).ready(function(){
$("button").click(function(){
$.get("http://www.liulongbin.top:3006/api/get",function(data,status){
alert("数据:" + data + "\n状态:" + status);
});
});
});
</script>
</head>
<body>
<button>向页面发送 HTTP GET 请求,然后获得返回的结果</button>
</body>
</html>
4.2 jQuery AJAX发起POST请求
<!DOCTYPE html>
<html>
<head>
<script src="/jquery/jquery-1.11.1.min.js">
</script>
<script>
$(document).ready(function(){
$("button").click(function(){
$.post("http://www.liulongbin.top:3006/api/post",
{
name:"Donald Duck",
city:"Duckburg"
},
function(data,status){
alert("数据:" + data + "\n状态:" + status);
});
});
});
</script>
</head>
<body>
<button>向页面发送 HTTP POST 请求,并获得返回的结果</button>
</body>
</html>
4. 同源策略
协议相同
域名相同
端口相同
非同源的网站会受到下列限制:
Cookie、LocalStorage 和 IndexDB 无法读取。
DOM 无法获得
AJAX 请求不能发送。(或者是请求发送之后,浏览器识别出不同源,将响应拦截了)
因为有同源策略的限制,当需要请求外部网站的数据时,就需要跨域。
5. 跨域
由于浏览器同源策略,AJAX 不能访问不同源的资源。这时候,就需要 跨域 。
关于同源策略现阶段一般用两种方法跨域:
1. JSONP 跨域原理
JSONP的最基本的原理是:动态添加一个
<script>
标签,而script标签的src属性是没有跨域的限制的。
- 事先在请求方页面中写定一个 callback 函数,用来获取响应方响应的数据。
- 在请求方页面中动态创建
<script>
标签,通过设置<script>
标签的src
属性对src
指向的网站发起请求。 - 需要将 1 中的 callback 函数名以查询参数的形式写入 2 中
<script>
标签的src
中,告知后端要执行的回调函数 - 响应方获得请求,返回一段JS代码(该段JS代码执行事先写好的 callback 函数,并将__要返回的数据作为 callback 函数的参数带入请求方__)
- 这时候,请求方就通过 callback 函数获得了请求的数据。
在实际使用中,通过两个约定来规范 JSONP 的使用:
- 使用查询参数指明 callback 的函数名,形如
?callback=函数名
- 查询参数中的函数名一般随机生成,使用完毕即删除,保证不污染全局变量。
JSOPN跨域请求例子:
function JSONP(path){
// 创建一个 script 标签
let script = document.createElement("script")
// 随机生成回调函数名
let functionName = 'callback' + parseInt(Math.random()*100000,10)
// 定义回调函数,处理获得的数据
window[functionName] = function(data){
console.log('获取的数据是:')
console.log(data)
alert('请求成功。')
}
// 设置JSONP请求路径
script.src = path + "?callback=" + functionName
// 将 script 标签插入到页面中
document.body.appendChild(script)
// 请求完成之后,删除回调函数,节约内存
delete window[functionName]
}
2. CORS(Cross-origin resource sharing)跨域资源共享
CORS 是解决跨域数据请求的终极解决方案
原理:CORS 跨域的使用方式是在后端代码中设置响应头,将响应资源的响应头设置成请求页面的源(间接使要响应的资源与请求同源)
response.setHeader('Access-Control-Allow-Origin', '发送请求的源地址')