文章目錄
- get請求
- 帶引數的get請求
- json字串和json格式
- get請求的封裝
- 基于promise的get請求的封裝
- post請求
- post請求的封裝
- utils.js封裝get和post請求
- get和post方法封裝成兩個
- get和post方法封裝成一個
- ajax例子-段子請求
- fetch方法
- 基于fetch的get請求
- 基于fetch的post請求
- 原因分析
- 瀏覽器的同源策略
- 定義
- 為什么要使用同源策略
- 舉例
- src屬性開放性原則
- 例子1
- 例子1(動態函式名)
- 例子(百度動態搜索框)
- 三次握手和四次揮手
- 初步理解
- 常見狀態碼
get請求
get.html
四個步驟
<!DOCTYPE html>
<body>
<button onclick="getReq()">get request</button>
<script>
function getReq(){
//1.創建一個XMLHttpRequest物件
let xhr = new XMLHttpRequest();
//2.呼叫open()方法打開連接
//引數:method: string, url: string
xhr.open("get","./data.php");
//3.發送請求
xhr.send();
//4.監聽狀態的改變
xhr.onreadystatechange = function(){
//判斷狀態值 0-4,五種狀態,4表示最終完成
if(xhr.readyState === 4){
//判斷狀態碼
if(xhr.status === 200){
console.log(xhr.responseText);
}
}
}
}
</script>
</body>
</html>
data.php
<?php
echo "hello ajax"
?>
帶引數的get請求
get.html
get方法傳遞引數拼接在url的后邊
<!DOCTYPE html>
<body>
<button onclick="getReq()">get request</button>
<script>
function getReq(){
//創建一個XMLHttpRequest物件
let xhr = new XMLHttpRequest();
//呼叫open()方法打開連接
//引數:method: string, url: string
xhr.open("get","./data.php?id=101");
//發送請求
xhr.send();
//監聽狀態的改變
xhr.onreadystatechange = function(){
//判斷狀態值 0-4,五種狀態,4表示最終完成
if(xhr.readyState === 4){
//判斷狀態碼
if(xhr.status === 200){
console.log(xhr.responseText);
}
}
}
}
</script>
</body>
</html>
data.php
<?php
$id = $_GET["id"];
echo "hello ajax $id"
?>
輸出


json字串和json格式
get.html
json字串和json格式
<!DOCTYPE html>
<body>
<button onclick="getReq()">get request</button>
<script>
function getReq(){
//創建一個XMLHttpRequest物件
let xhr = new XMLHttpRequest();
//呼叫open()方法打開連接
//引數:method: string, url: string
xhr.open("get","./data.php?id=101");
//發送請求
xhr.send();
//監聽狀態的改變
xhr.onreadystatechange = function(){
//判斷狀態值 0-4,五種狀態,4表示最終完成
if(xhr.readyState === 4){
//判斷狀態碼
if(xhr.status === 200){
console.log(xhr.responseText);
console.log(JSON.parse(xhr.responseText));
}
}
}
}
</script>
</body>
</html>
data.php
<?php
$id = $_GET["id"];
echo json_encode(array(
'id' => $id,
'title' => 'hello ajax'
))
?>
get請求的封裝
getAjax.html
如何去掉末尾的一個字符&?使用slice函式
<!DOCTYPE html>
<body>
<button onclick="get()">post request</button>
<script>
function get(){
let per = {
name:"zhuobing",
age: 19
}
getAjax("./data.php",per,function(resp){
console.log(resp);
},true)
}
//封裝函式:getAjax()
//url:請求的地址
//query:請求的引數,是個物件
//callback:回呼函式
//isJson:是否決議成JSON
function getAjax(url,query,callback,isJson){
if(query){
url += '?';
for(let key in query){
url += `${key}=${query[key]}&`
}
url = url.slice(0,-1);
}
let xhr = new XMLHttpRequest();
xhr.open("get",url);
xhr.send();
xhr.onreadystatechange = function(){
//判斷狀態值 0-4,五種狀態,4表示最終完成
if(xhr.readyState === 4){
//判斷狀態碼
if(xhr.status === 200){
let resp = isJson? JSON.parse(xhr.responseText):xhr.responseText;
callback(resp);
}
}
}
}
</script>
</body>
</html>
data.php
<?php
$name = $_GET["name"];
$age = $_GET["age"];
echo json_encode(array(
"name" => $name,
"age" => $age
))
?>
基于promise的get請求的封裝
test.html
<!DOCTYPE html>
<html lang="zh">
<body>
<button onclick="sendMsg()">get request by promise</button>
<script src="./utils.js"></script>
<script>
function sendMsg() {
utils.fetch("./data2.php", { name: "zhuobing", age: 19 }, true).then(function (resp) {
console.log(resp);
})
}
</script>
</body>
</html>
utils.js
promise使用的關鍵就是回傳一個new promise()物件
const utils = {
//基于promise的get封裝
fetch:function(url,query,isJson){
if(query){
url += '?';
for(let key in query){
url += `${key}=${query[key]}&`
}
url = url.slice(0,-1);
}
return new Promise((resolve,reject)=>{
let xhr = new XMLHttpRequest();
xhr.open("get",url);
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
//判斷狀態碼
if(xhr.status === 200){
let resp = isJson? JSON.parse(xhr.responseText):xhr.responseText;
resolve(resp);
}else{
reject();
}
}
}
})
}
}
post請求
post.html
JavaScript中模板字串的寫法
<!DOCTYPE html>
<body>
<button onclick="getReq()">post request</button>
<div></div>
<script>
function getReq(){
//創建一個XMLHttpRequest物件
let xhr = new XMLHttpRequest();
//呼叫open()方法打開連接
//引數:method: string, url: string
xhr.open("post","./data.php");
//設定請求頭的Content-Type
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
//發送請求
xhr.send("name=zhuobing&age=19");
//監聽狀態的改變
xhr.onreadystatechange = function(){
//判斷狀態值 0-4,五種狀態,4表示最終完成
if(xhr.readyState === 4){
//判斷狀態碼
if(xhr.status === 200){
let resp = JSON.parse(xhr.responseText);
document.querySelector("div").innerHTML=`
<h2>name=${resp.name}</h2>
<h2>age=${resp.age}</h2>
`
}
}
}
}
</script>
</body>
</html>
data.php
<?php
$name = $_POST["name"];
$age = $_POST["age"];
echo json_encode(array(
"name" => $name,
"age" => $age
))
?>
輸出
post傳遞引數和get傳遞引數的區別


post請求的封裝
post.html
<!DOCTYPE html>
<body>
<button onclick="post()">post request</button>
<div></div>
<script>
function post(){
let per = {
name:"zhuobing",
age: 19
}
postAjax("./data.php",per,function(resp){
console.log(resp);
},true)
}
function postAjax(url,query,callback,isJson){
let para = '';
if(query){
for(let key in query){
para += `${key}=${query[key]}&`
}
para = para.slice(0,-1);
}
console.log(para);
let xhr = new XMLHttpRequest();
xhr.open("post",url);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(para);
xhr.onreadystatechange = function(){
//判斷狀態值 0-4,五種狀態,4表示最終完成
if(xhr.readyState === 4){
//判斷狀態碼
if(xhr.status === 200){
let resp = isJson? JSON.parse(xhr.responseText):xhr.responseText;
callback(resp);
}
}
}
}
</script>
</body>
</html>
data.php
<?php
$name = $_POST["name"];
$age = $_POST["age"];
echo json_encode(array(
"name" => $name,
"age" => $age
))
?>
utils.js封裝get和post請求
get和post方法封裝成兩個
test.html
呼叫外部工具utils.js的方式
<!DOCTYPE html>
<body>
<button onclick="post()">post request</button>
<button onclick="get()">get request</button>
<script src="./utils.js"></script>
<script>
function post(){
let per = {
name:"postMethod",
age: 19
}
//post方式請求資料
utils.post("./data.php",per,function(resp){
console.log(resp);
},true)
}
function get(){
let per = {
name:"getMethod",
age: 19
}
//get方式請求資料
utils.get("./data2.php",per,function(resp){
console.log(resp);
},true)
}
</script>
</body>
</html>
utils.js
代碼折疊
const utils = {
get: function(url,query,callback,isJson){
if(query){
url += '?';
for(let key in query){
url += `${key}=${query[key]}&`
}
url = url.slice(0,-1);
}
let xhr = new XMLHttpRequest();
xhr.open("get",url);
xhr.send();
xhr.onreadystatechange = function(){
//判斷狀態值 0-4,五種狀態,4表示最終完成
if(xhr.readyState === 4){
//判斷狀態碼
if(xhr.status === 200){
let resp = isJson? JSON.parse(xhr.responseText):xhr.responseText;
callback(resp);
}
}
}
},
post: function(url,query,callback,isJson){
let para = '';
if(query){
for(let key in query){
para += `${key}=${query[key]}&`
}
para = para.slice(0,-1);
}
let xhr = new XMLHttpRequest();
xhr.open("post",url);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(para);
xhr.onreadystatechange = function(){
//判斷狀態值 0-4,五種狀態,4表示最終完成
if(xhr.readyState === 4){
//判斷狀態碼
if(xhr.status === 200){
let resp = isJson? JSON.parse(xhr.responseText):xhr.responseText;
callback(resp);
}
}
}
}
}
get和post方法封裝成一個
test.html
<!DOCTYPE html>
<body>
<button onclick="request()">request</button>
<script src="./utils.js"></script>
<script>
function request(){
utils.ajax({
method:'get',
url:'data2.php',
query:{name:'getMethod',age:19},
callback:function(resp){
console.log(resp);
},
isJson:true
});
utils.ajax({
method:'post',
url:'data.php',
query:{name:'postMethod',age:19},
callback:function(resp){
console.log(resp);
},
isJson:true
});
}
</script>
</body>
</html>
utils.js
代碼折疊
const utils = {
// params: object {method,url,query,callback,isJson}
ajax: function(params){
let xhr = new XMLHttpRequest();
if(params.method.toLowerCase() ==="post"){
let para = '';
if(params.query){
for(let key in params.query){
para += `${key}=${params.query[key]}&`
}
para = para.slice(0,-1);
}
xhr.open("post",params.url);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(para);
}else{
if(params.query){
params.url += '?';
for(let key in params.query){
params.url += `${key}=${params.query[key]}&`
}
params.url = params.url.slice(0,-1);
}
xhr.open("get",params.url);
xhr.send();
}
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200){
let resp = params.isJson? JSON.parse(xhr.responseText):xhr.responseText;
params.callback(resp);
}
}
}
}
}
ajax例子-段子請求
index.html
sid的傳遞程序
<!DOCTYPE html>
<html lang="zh">
<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>ajax</title>
</head>
<body>
<ul id="wrap"></ul>
<script src="./utils.js"></script>
<script>
utils.ajax({
method:"get",
url:"https://api.apiopen.top/getJoke",
query: null,
callback: function(resp){
let html = '';
resp.result.forEach(ele => {
html += `
<li>
<h3>${ele.text}</h3>
<button data-id=${ele.sid}>查看作者</button>
</li>
`
});
document.querySelector("#wrap").innerHTML = html;
},
isJson:true
});
document.querySelector("#wrap").onclick = function(e){
let target = e.target;
if(target.tagName === "BUTTON"){
let id = target.getAttribute("data-id");
utils.ajax({
method: "get",
url: "https://api.apiopen.top/getSingleJoke",
query: {sid:id},
callback:function(resp){
let name = resp.result.name;
let span = document.createElement("span");
span.innerHTML = name;
target.parentNode.appendChild(span);
},
isJson:true
});
}
}
</script>
</body>
</html>
utils.js
const utils = {
// params: object {method,url,query,callback,isJson}
ajax: function(params){
let xhr = new XMLHttpRequest();
if(params.method.toLowerCase() ==="post"){
let para = '';
if(params.query){
for(let key in params.query){
para += `${key}=${params.query[key]}&`
}
para = para.slice(0,-1);
}
xhr.open("post",params.url);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(para);
}else{
if(params.query){
params.url += '?';
for(let key in params.query){
params.url += `${key}=${params.query[key]}&`
}
params.url = params.url.slice(0,-1);
}
xhr.open("get",params.url);
xhr.send();
}
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200){
let resp = params.isJson? JSON.parse(xhr.responseText):xhr.responseText;
params.callback(resp);
}
}
}
}
}
OUTPUT


fetch方法
基于fetch的get請求
test.html
為什么需要多個以then()
<!DOCTYPE html>
<html lang="zh">
<body>
<button onclick="sendMsg()">get request by promise</button>
<script>
function sendMsg() {
fetch("./data2.php?name=zhuobing&age=19")
.then(function(resp){
return resp.json()
})
.then(function (resp) {
console.log(resp);
})
}
</script>
</body>
</html>
基于fetch的post請求
test.html
這是一個出現問題的代碼,編譯器也沒有報錯,但是就是找不到原因在哪里
<!DOCTYPE html>
<html lang="zh">
<body>
<button onclick="sendMsg()">post request by promise</button>
<script>
function sendMsg() {
fetch("https://api.apiopen.top/getSingleJoke", {
method: 'post',
body: JSON.stringify({ 'sid': 28822773 })//這里是要傳遞的引數
})
.then(response => response.json())
.then(data => {
console.log(data)
})
}
</script>
</body>
</html>
test.html
這個代碼是修改之后的代碼,得到了期望的效果
修改之處
出現問題的地方
<!DOCTYPE html>
<html lang="zh">
<body>
<button onclick="sendMsg()">post request by promise</button>
<script>
function sendMsg() {
fetch("https://api.apiopen.top/getSingleJoke", {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
// body: JSON.stringify({ sid: 28822773 })//沒有報錯,但是就是找不到錯誤的原因
body: "sid=28822773"//竟然得到了正確的結果
})
.then(response => response.json())
.then(data => {
console.log(data)
})
}
</script>
</body>
</html>
原因分析
fetch官網post傳遞資料用的是JSON.stringify()的形式:
fetch('http://www.tingchunyu.com/test/fetch_test/fetch_getuser_test.php', {
body: JSON.stringify({id:666}),
headers: {
'content-type': 'application/json'
},
method: 'POST',
})
.then(response => {
if (response.ok){//判斷請求是否成功
return response.json()
}
throw new Error('請求發生錯誤')
})
.then(data=>{
console.log(data)
})
.catch(error => {
console.log(error)
})
但是像上面這樣寫后臺按照以前接收變數的方式總是接收null,造成這個的原因是因為這樣向服務器提交的資料是一個json資料,而不是傳統的formdata,如下圖所示:


因此想讓后臺接收到資料有以下兩種解決方法
- 將上面代碼body的格式做以下修改
body: 'id=666'
//如果有多個引數可以用"&"進行連接 如:body: 'id=666&type=0'
但是這種寫法如果有許多引數要傳遞的話就有點麻煩了,
第二種方法,保持以上代碼不變,修改后臺接收引數的方式,以PHP為例:
// 將 $_POST['id']修改成以下方式
$data = json_decode(file_get_contents('php://input'),true);
$id = $data['id'];//這樣就可以接收到ID了
瀏覽器的同源策略
定義
兩個頁面地址中的協議,域名,埠號一致,則表示同源,
同源策略的限制:不能通過ajax請求不同域的資料,不能通過腳本操作不同域下的DOM,
為什么要使用同源策略
設定同源限制主要是為了安全,如果沒有同源限制存在瀏覽器中的cookie等其他資料可以任意讀取,不同域下DOM任意操作,ajax任意請求的話如果瀏覽了惡意網站那么就會泄漏這些隱私資料
舉例

src屬性開放性原則

例子1
test.html
<!DOCTYPE html>
<html lang="en">
<body>
<script>
function fun(resp){
console.log(resp);
}
</script>
<script src="http://localhost/data3.php"></script>
</body>
</html>
data3.php
回傳的結果
因為無論script標簽的src引入的是什么型別的問題,都會把它當做js代碼來執行,所以fun(123)被當做一個函式來執行,也就是上面寫好的函式,在后端的php代碼中只是增加了一個引數123
<?php
echo "fun(123)";
?>
輸出


例子1(動態函式名)
test.html
跨域的流程
<!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>
</head>
<body>
<script>
function adfsadsfadsf(resp){
console.log(resp);
}
</script>
<script src="http://localhost/data3.php?funname=adfsadsfadsf"></script>
</body>
</html>
data3.php
函式名字的傳遞程序
<?php
$fun = $_GET["funname"];
echo "$fun(123)";
?>
后端回傳的結果

例子(百度動態搜索框)
test.html
為什么需要[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-iy13l6oX-1634570238268)(C:\Users\zhuoss\AppData\Roaming\Typora\typora-user-images\image-20210717145405358.png)]
因為在如果不remove,html中將會有許多的script標簽,會嚴重的影響瀏覽器的性能
回呼函式
<!DOCTYPE html>
<html lang="zh">
<head>
</head>
<body>
<input id="search" type="text">
<ul id="list"></ul>
<script>
let search = document.querySelector("#search")
search.onkeyup = function(){
let text = search.value
let script = document.createElement("script")
script.src = `https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=${text}&cb=fun`
document.body.appendChild(script)
document.body.removeChild(script)
}
function fun(resp){
let html = ''
resp.s.forEach(ele => {
html += `<li>${ele}</li>`
});
document.querySelector("#list").innerHTML = html
}
</script>
</body>
</html>
輸出

三次握手和四次揮手
初步理解
建立連接需要三次握手,斷開連接需要四次揮手

常見狀態碼

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/325610.html
標籤:其他
上一篇:你會用ES6,那倒是用啊!


















