get请求
get.html
四个步骤
<!DOCTYPE html>
<body>
<button onclick="getReq()">get request</button>
<script>
function getReq(){
let xhr = new XMLHttpRequest();
xhr.open("get","./data.php");
xhr.send();
xhr.onreadystatechange = function(){
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(){
let xhr = new XMLHttpRequest();
xhr.open("get","./data.php?id=101");
xhr.send();
xhr.onreadystatechange = function(){
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(){
let xhr = new XMLHttpRequest();
xhr.open("get","./data.php?id=101");
xhr.send();
xhr.onreadystatechange = function(){
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)
}
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(){
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 = {
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(){
let xhr = new XMLHttpRequest();
xhr.open("post","./data.php");
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send("name=zhuobing&age=19");
xhr.onreadystatechange = function(){
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(){
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
}
utils.post("./data.php",per,function(resp){
console.log(resp);
},true)
}
function get(){
let per = {
name:"getMethod",
age: 19
}
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(){
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(){
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 = {
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 = {
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: "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'
但是这种写法如果有许多参数要传递的话就有点麻烦了。
第二种方法,保持以上代码不变。修改后台接收参数的方式。以PHP为例:
$data = json_decode(file_get_contents('php://input'),true);
$id = $data['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>
输出
三次握手和四次挥手
初步理解
建立连接需要三次握手,断开连接需要四次挥手
常见状态码
|