方法一:經過form表單請求和響應javascript
能夠post,刷新可經過iframe局部刷新css
index.htmlhtml
<!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發送請求java
直接在服務器中修改node
**此方法沒有辦法post,只能get,不安全ajax
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.jsjson
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() } /********************/
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?(瞭解一下)
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 } } })
待補充......