三种方法造get请求
方法一:通过form表单请求和响应
可以post,刷新可通过iframe局部刷新
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="style.css"> <title>button</title> </head> <body> <h5>您的账户余额是 <span id="amount">&&amount&&</span></h5> <form action="/pay" method="POST" target="result"> <!-- post方法 --> <input type="submit" name="number" value="付款"> </form> <iframe name="result" src="about:blank" frameborder="0" height="100"></iframe> <!-- 一个老办法 在iframe中承载刷新 --> </body> </html>
server.js
var http = require('http') var fs = require('fs') var url = require('url') var port = process.argv[2] if (!port) { console.log('请指定端口号\nnode server.js 8888 ') process.exit(1) } var server = http.createServer(function (request, response) { var parsedUrl = url.parse(request.url, true) var pathWithQuery = request.url var queryString = '' if (pathWithQuery.indexOf('?') >= 0) { queryString = pathWithQuery.substring(pathWithQuery.indexOf('?')) } var path = parsedUrl.pathname var query = parsedUrl.query var method = request.method /********************/ console.log('含查询字符串的路径\n' + pathWithQuery) console.log('HTTP路径为\n' + path) if (path == '/') { var string = fs.readFileSync('./index.html', 'utf8') var amount = fs.readFileSync('./db', 'utf8')//同步读取db这个文件,其中内容的值是100,类型是字符串 string = string.replace('&&amount&&', amount)//&&amount&&为占位符 response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write(string) response.end() } else if (path == '/style.css') { var string = fs.readFileSync('./style.css', 'utf8') response.setHeader('Content-Type', 'text/css') response.write(string) response.end() } else if (path == '/main.js') { var string = fs.readFileSync('./main.js', 'utf8') response.setHeader('Content-Type', 'application/javascript') response.write(string) response.end() } else if (path === '/pay' && method.toUpperCase() === 'POST') { var amount = fs.readFileSync('./db', 'utf8')//读取当前数据库中存储的数据 var newAmount = amount - 1//amount是字符串类型,-1后自动转成数字类型 fs.writeFileSync('./db',newAmount)//将newAmount存到db中 response.write('success')//告知成功 response.end() } else { response.statusCode = 404 response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write('找不到对应的路径,需自行修改') response.end() } /*******************/ }) server.listen(port) console.log('监听 ' + port + ' 成功\n 请打开 http://localhost:' + port)
方法二:通过image发送请求
直接在服务器中修改
**此方法没有办法post,只能get,不安全
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="style.css"> <title>button</title> </head> <body> <h5>您的账户余额是 <span id="amount">&&amount&&</span></h5> <button id="button">支付</button> <script src="main.js"></script> </body> </html>
main.js
button.addEventListener('click', (e) => {
let image = document.createElement('img') image.src = '/pay' //告知用户请求成功 image.onload = function () { alert('打钱成功') amount.innerText = amount.innerText - 1 //成功则自动减一 } //告知用户请求失败 image.onerror = function () { alert('打钱失败') } })
server.js
/*******************/ console.log('含查询字符串的路径\n' + pathWithQuery) console.log('HTTP路径为\n' + path) if (path == '/') { var string = fs.readFileSync('./index.html', 'utf8') var amount = fs.readFileSync('./db', 'utf8')//同步读取db这个文件,其中内容的值是100,类型是字符串 string = string.replace('&&amount&&', amount)//&&amount&&为占位符 response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write(string) response.end() } else if (path == '/style.css') { var string = fs.readFileSync('./style.css', 'utf8') response.setHeader('Content-Type', 'text/css') response.write(string) response.end() } else if (path == '/main.js') { var string = fs.readFileSync('./main.js', 'utf8') response.setHeader('Content-Type', 'application/javascript') response.write(string) response.end() } else if (path === '/pay') { var amount = fs.readFileSync('./db', 'utf8')//读取当前数据库中存储的数据 var newAmount = amount - 1//amount是字符串类型,-1后自动转成数字类型 //模拟支付失败 if (Math.random() > 0.5) { fs.writeFileSync('./db', newAmount)//将newAmount存到db中 response.setHeader('Content-Type', 'image/png') response.statusCode = 200//返回状态码200告知浏览器请求可以,从而告知用户支付成功 response.write(fs.readFileSync('./1.png'))//给浏览器一个实质的图片以避免浏览器不接受图片的请求 } else { response.statusCode = 400//同理反之 response.write('fail') } response.end() } else { response.statusCode = 404 response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write('找不到对应的路径,需自行修改 index.js') response.end() } /*******************/
方法三:通过script发送请求
SRJ
server rendered javascript 服务器返回javascript
只有get没有post
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="style.css"> <title>button</title> </head> <body> <h5>您的账户余额是 <span id="amount">&&amount&&</span></h5> <button id="button">支付</button> <script src="main.js"></script> </body> </html>
main.js
button.addEventListener('click', (e) => { let script = document.createElement('script') script.src='/pay' document.body.appendChild(script) script.onload=function(e){ e.currentTarget.remove()//删除每次点击执行时生成的script } script.onerror=function(e){ alert('fail') e.currentTarget.remove()//同上删除script } })
server.js
/********************/ console.log('含查询字符串的路径\n' + pathWithQuery) console.log('HTTP路径为\n' + path) if (path == '/') { var string = fs.readFileSync('./index.html', 'utf8') var amount = fs.readFileSync('./db', 'utf8')//同步读取db这个文件,其中内容的值是100,类型是字符串 string = string.replace('&&amount&&', amount)//&&amount&&为占位符 response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write(string) response.end() } else if (path == '/style.css') { var string = fs.readFileSync('./style.css', 'utf8') response.setHeader('Content-Type', 'text/css') response.write(string) response.end() } else if (path == '/main.js') { var string = fs.readFileSync('./main.js', 'utf8') response.setHeader('Content-Type', 'application/javascript') response.write(string) response.end() } else if (path === '/pay') { var amount = fs.readFileSync('./db', 'utf8')//读取当前数据库中存储的数据 var newAmount = amount - 1//amount是字符串类型,-1后自动转成数字类型 //模拟支付失败 if (Math.random() > 0.5) { fs.writeFileSync('./db', newAmount)//将newAmount存到db中 response.setHeader('Content-Type', 'application/javascript') response.statusCode = 200//返回状态码200告知浏览器请求可以,从而告知用户支付成功 response.write(` alert("success") amount.innerText=amount.innerText-1 `)//服务器返回了在浏览器执行的代码 } else { response.statusCode = 400//同理反之 response.write('faile') } response.end() } else { response.statusCode = 404 response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write('找不到对应的路径,需自行修改 index.js') response.end() } /********************/
模拟两个网站之间通过SRJ交流
8001调用8002的数据库
修改main.js
button.addEventListener('click', (e) => { let script = document.createElement('script') script.src='http://localhost:8002/pay' document.body.appendChild(script) script.onload=function(e){ e.currentTarget.remove()//删除每次点击执行时生成的script } script.onerror=function(e){ alert('fail') e.currentTarget.remove()//同上 } })
关于耦合和解耦
后端代码里面有前端的js代码,这个是对前端按钮的细节处理,这叫耦合
解决这个问题叫解耦
完整代码:
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="style.css"> <title>button</title> </head> <body> <h5>您的账户余额是 <span id="amount">&&amount&&</span></h5> <button id="button">支付</button> <script src="main.js"></script> </body> </html>
main.js
button.addEventListener('click', (e) => { let script = document.createElement('script') let functionName='callcall'+parseInt(Math.random()*100000,10)//随机函数名,避免污染全局变量,用完就delete window[functionName]=function(result){ if(result==='success'){ alert('支付成功') amount.innerText=amount.innerText-1 }else{ } } script.src='http://localhost:8002/pay?callback='+functionName//约定:这里的callbackName为callback document.body.appendChild(script) script.onload=function(e){ e.currentTarget.remove()//删除每次点击执行时生成的script delete window[functionName]//随机函数只用一次,用完就去掉 } script.onerror=function(e){ alert('支付失败') e.currentTarget.remove()//同上 delete window[functionName] } })
server.js
/********************/ console.log('含查询字符串的路径\n' + pathWithQuery) console.log('HTTP路径为\n' + path) if (path == '/') { var string = fs.readFileSync('./index.html', 'utf8') var amount = fs.readFileSync('./db', 'utf8')//同步读取db这个文件,其中内容的值是100,类型是字符串 string = string.replace('&&amount&&', amount)//&&amount&&为占位符 response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write(string) response.end() } else if (path == '/style.css') { var string = fs.readFileSync('./style.css', 'utf8') response.setHeader('Content-Type', 'text/css') response.write(string) response.end() } else if (path == '/main.js') { var string = fs.readFileSync('./main.js', 'utf8') response.setHeader('Content-Type', 'application/javascript') response.write(string) response.end() } else if (path === '/pay') { var amount = fs.readFileSync('./db', 'utf8')//读取当前数据库中存储的数据 var newAmount = amount - 1//amount是字符串类型,-1后自动转成数字类型 //模拟支付失败 if (Math.random() > 0.5) { fs.writeFileSync('./db', newAmount)//将newAmount存到db中 response.setHeader('Content-Type', 'application/javascript') response.statusCode = 200//返回状态码200告知浏览器请求可以,从而告知用户支付成功 response.write(` ${query.callback}.call(undefined,'success') `)//*********此处解耦,后端将前端传的参数放在call前面******** } else { response.statusCode = 400//同理反之 response.write('fail') } response.end() } else { response.statusCode = 404 response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write('找不到对应的路径,需自行修改 index.js') response.end() } /********************/
总结JSONP
为什么叫JSONP?(了解一下)
json+padding -- JSONP
JSONP的实质?
JSONP解决两个网站之间的交流,即利用动态标签进行跨域请求。(用script标签,script标签不受域名限制,AJAX受域名限制)
详述:
请求方:浏览器(某网前端)
响应方:服务器(另某网后端)
1.请求方创建script,src指向响应方,同时传一个查询参数?callback=随机数xxx(约定)
2.响应方根据查询参数callback,构造形如
随机数xxx.call(undefined,'要的数据')
这样的响应
3.浏览器接收到响应,就会执行随机数xxx.call(undefined,'要的数据')
4.请求方得到要的数据
为什么JSONP不能支持POST请求?
1.JSONP是通过动态创建script实现的
2.动态创建script时只能用get,没办法用post
用Jquery实现JSONP
$.ajax({ url: "http://jack.com:8002/pay", dataType: "jsonp", success: function( response ) { if(response === 'success'){ amount.innerText = amount.innerText - 1 } } })
待补充......