JSONP的格式
2021-08-22_110634.pngJSONP 不支持 POST的原因
- i、因为JSONP是通过创建script实现的
- ii、动态创建script只能用get,不能用post
简单理解什么是数据库
1、文件系统是一种数据库 2、MySQL 是一种数据库
只要能长久地存数据,就是数据库
先了解服务器和网页是怎么样进行交互的,慢慢发展到利用JSONP的技术和结合jquery方便快捷实现,其中原理结合代码和注释理解,这里只展示最关键代码,具体完整代码看我给出的github链接
1、前端页面请求和服务器响应
前端页面:index.html
需求:点击付款信息,账户余额就会减少
<title>首页</title>
<link rel="stylesheet" href="/style.css">
<h5>你的账户余额是:<span id='amount'>100</span></h5>
<button id="button">付款1块钱</button>
<script >
button.addEventListener('click',(e)=>{
let n=amount.innerText
let number = parseInt(n,10)
let newNumber=number-1
amount.innerText=newNumber
})
</script>
服务器:index.js
if(path === '/'){ // 如果用户请求的是 / 路径
var string = fs.readFileSync('./index.html')
response.setHeader('Content-Type', 'text/html;charset=utf-8')
response.end(string)
}else if(path === '/style.css'){
var string = fs.readFileSync('./style.css')
response.setHeader('Content-Type', 'text/css')
response.end(string)
}else if(path === '/main.js'){
var string = fs.readFileSync('./main.js')
response.setHeader('Content-Type', 'application/javascript')
response.end(string)
}else{
response.statusCode = 404
response.setHeader('Content-Type', 'text/html;charset=utf-8')
response.end('找不到对应的路径,你需要自行修改 index.js')
}
这种请求,做的付款信息,当刷新页面时候,数据就会重新刷新。所以我们需要服务器这里需要添加数据库,由数据库进行读写数据,前端只是发起请求,服务器做出响应修改数据库内容。
2、添加数据库db(也就是一种文件存储数据)
前端页面:index.html
<title>首页</title>
<link rel="stylesheet" href="/style.css">
<h5>你的账户余额是:<span id='amount'>&&&amount&&&</span></h5>
<button id="button">付款1块钱</button>
<script >
button.addEventListener('click',(e)=>{
let n=amount.innerText
let number = parseInt(n,10)
let newNumber=number-1
amount.innerText=newNumber
})
</script>
<h5>你的账户余额是:<span id='amount'>&&&amount&&&</span></h5>
这里先用&&&amount&&&
代表占位符,响应时候再取得后台服务器数据库db的数据再替换。
服务器:index.js
if(path === '/'){ // 如果用户请求的是 / 路径
var string = fs.readFileSync('./index.html','utf-8')
var amount = fs.readFileSync('./db','utf-8')
string = string.replace('&&&amount&&&',amount)
response.setHeader('Content-Type', 'text/html;charset=utf-8')
response.end(string)
}else if(path === '/style.css'){
var string = fs.readFileSync('./style.css')
response.setHeader('Content-Type', 'text/css')
response.end(string)
}else if(path === '/main.js'){
var string = fs.readFileSync('./main.js')
response.setHeader('Content-Type', 'application/javascript')
response.end(string)
}else{
response.statusCode = 404
response.setHeader('Content-Type', 'text/html;charset=utf-8')
response.end('找不到对应的路径,你需要自行修改 index.js')
}
var amount = fs.readFileSync('./db','utf-8')
先读取数据库db数据
string = string.replace('&&&amount&&&',amount)
占位符替换成读到的数据
3、实现页面的局部刷新(优化用户体验1)
方案一:用图片造 get 请求
前端页面:index.html
<title>首页</title>
<link rel="stylesheet" href="/style.css">
<h5>你的账户余额是:<span id='amount'>&&&amount&&&</span></h5>
<button id="button">付款</button>
<script >
button.addEventListener('click',(e)=>{
let image=document.createElement('img')
image.src='/pay'
image.onload=function(){ // 状态码是 200~299 则表示成功
alert('付款成功')
amount.innerText=amount.innerText-1 //后台数据库成功修改后,成功则页面同步修改
}
image.onerror=function(){ // 状态码大于等于 400 则表示失败
alert('付款失败')
}
})
</script>
image.onload=function(){ }
通过状态码知道响应成功则执行里面代码
image.onerror=function(){ }
通过状态码知道响应失败则执行里面代码
服务器:index.js(新增路径为/pay代码)
else if (path === '/pay'){
var amount = fs.readFileSync('./db','utf-8')
var newAmount=amount-1
if(Math.random()>0.5){
fs.writeFileSync('./db',newAmount)
response.setHeader('Content-Type', 'image/jpg')
response.statusCode=200
response.write(fs.readFileSync('./dog.jpg'))
}else{
response.statusCode=400
response.write('fail')
}
response.end()
}
Math.random()
随机生成一个在0-1之间的数据
fs.writeFileSync('./db',newAmount)
将新数据写进数据库db中
response.statusCode=200
状态码是为了识别数据是否改写成功
response.write(fs.readFileSync('./dog.jpg'))
用图片造 get 请求,需读出照片
方案二:用 script 造 get 请求
前端页面:index.html
<title>首页</title>
<link rel="stylesheet" href="/style.css">
<h5>你的账户余额是:<span id='amount'>&&&amount&&&</span></h5>
<button id="button">付款</button>
<script >
button.addEventListener('click',(e)=>{
let script=document.createElement('script')
script.src='/pay'
document.body.appendChild(script)
script.onload=function(e){ //onload事件是在script事件执行完触发
e.currentTarget.remove()
}
// script.onload=function(){ *这部分由服务器中index.js执行*
// amount.innerText=amount.innerText-1
// }
script.onerror=function(e){ // 状态码大于等于 400 则表示失败
alert('付款失败')
e.currentTarget.remove()
}
})
</script>
let script=document.createElement('script')
动态创建一个script标签
document.body.appendChild(script)
这个script标签要挂在body下,image请求就不用,script请求就要(谨记)
e.currentTarget.remove()
响应不论成功和失败都要移除script标签
服务器:index.js(新增路径为/pay代码)
else if(path === '/pay'){
var amount = fs.readFileSync('./db','utf-8')
var newAmount=amount-1
if(Math.random()>0.5){
fs.writeFileSync('./db',newAmount)
response.setHeader('Content-Type', 'application/javascript')
response.statusCode=200
response.write(`
amount.innerText=amount.innerText-1
`)
}else{
response.statusCode=400
response.write('fail')
}
response.end()
response.write(` amount.innerText=amount.innerText-1 `)
这部分前端页面是能读取到这个响应的,所以页面数据会刷新。
4、实现跨域访问(两个域名之间的访问)
需求:http://fei.com访问http://jack.com的服务器(请求方给一个查询参数,响应方根据查询参数构造对应响应)
1、用记事本打开 hosts文件(菜单->文件->定位到C:\Windows\System32\drivers\etc),修改hosts内容。
hosts文件新增内容:
127.0.0.1 fei.com
127.0.0.1 jack.com
打开两个git bash窗口,设置两个端口打开浏览器
PORT=8001 node index.js
http://fei.com:8001
PORT=8002 node index.js
http://jack.com:8002
fei.com前端页面:
<title>首页</title>
<link rel="stylesheet" href="/style.css">
<h5>你的账户余额是:<span id='amount'>&&&amount&&&</span></h5>
<button id="button">付款</button>
<script >
button.addEventListener('click',(e)=>{
let script=document.createElement('script')
let functionName='fei'+parseInt(Math.random()*100000,10)
window[functionName]=function(result){
// alert('我是fei.com写的代码')
// alert(`我得到的结果是${result}`)
if(result === 'success'){
amount.innerText=amount.innerText-1
}else{
}
}
script.src='http://jack.com:8002/pay?callback='+functionName
document.body.appendChild(script)
script.onload=function(e){ //onload事件是在script事件执行完触发
e.currentTarget.remove()
delete window[functionName]
}
script.onerror=function(e){ // 状态码大于等于 400 则表示失败
alert('付款失败')
e.currentTarget.remove()
delete window[functionName]
}
})
</script>
1、let functionName='fei'+parseInt(Math.random()*100000,10)
随机生产一个查询参数
2、 script.src='http://jack.com:8002/pay?callback='+functionName
访问jack服务器,同时传给服务器一个查询参数
3、delete window[functionName]
最后运行完,要删除这个随机产生的查询参数
jack.com后端服务器:
else if(path === '/pay'){
var amount = fs.readFileSync('./db','utf-8')
var newAmount=amount-1
if(Math.random()>0.5){
fs.writeFileSync('./db',newAmount)
response.setHeader('Content-Type', 'application/javascript')
response.statusCode=200
response.write(`
${query.callback}.call(undefined,'success')
`)
}else{
response.statusCode=400
response.write('fail')
}
response.end()
${query.callback}.call(undefined,'success')
服务器查询传入的查询参数
5、利用jquery能快速实现完成跨域访问(两个域名之间的访问)
fei.com前端页面:
<title>首页</title>
<link rel="stylesheet" href="/style.css">
<h5>你的账户余额是:<span id='amount'>&&&amount&&&</span></h5>
<button id="button">付款</button>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js'></script>
<script >
//用jquery能快速实现fei.com访问jack.com
button.addEventListener('click',(e)=>{
$.ajax({
url: "http://jack.com:8002/pay", //访问的地址需要输入
jsonp: "callback",
dataType: "jsonp",
success: function(result) { //响应后需要进行处理输入
if(result === 'success'){
amount.innerText=amount.innerText-1
}
}
});
注意可以运用这个模板能快速实现跨域访问,注意里面写的ajax,用的不是ajax方法这个还是jquery的方法。
网友评论