能长久的存放数据就是数据库!
if(path === '/'){
var string = fs.readFileSync('./index.html','utf8')
var amount = fs.readFileSync('./db','utf8')//同步读一个文件
string=string.replace('&&&amount&&&',amount)
可以用&&&amount&&&在HTML中当占位符,后端处理数据的时候替换掉这个占位符就行了
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
fs.writeFileSync('./db',newAmount)
response.write('success!')
response.end()
}
else{
response.statusCode = 404
response.setHeader('Content-type','text/html;charset=utf-8')
response.write('找不到对应的路径')
response.end()
}
html页面用form表单提交一个post请求,服务器改变数据再返回刷新到页面
一开始是用iframe在页面上显示改变数据,太古老,已经被众人忘记
想到用img创建请求 但是只能创建get请求
浏览器一旦发现img标签,就会发送一个请求,就是img的src
let img = document.createElement('img')
img.src = '/pay'
img.onload = function () {
alert('success')
window.location.reload() //页面刷新
}
img.onerror = function () {
alert('false')
}
var amount = fs.readFileSync('./db','utf8')//同步读一个文件
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('./1.jpg'))
}
else{
response.statusCode = 400
response.write('fail')
}
response.end()
onload加载成功 onerror 加载失败 因为假的图片骗不了浏览器必须要用一张真的图片
用状态码来判断是否请求成功
用script标签发送请求
button.onclick = function () {
let script = document.createElement('script')
script.src='/pay'
document.body.appendChild(script)
script.onload=function(){
alert('success')
amount.innerText = amount.innerText-1;
}
script.onerror=function(){
alert('fail')
}
}
else if(path === '/pay'){
var amount = fs.readFileSync('./db','utf8')//同步读一个文件
var newAmount = amount - 1
if(Math.random()>0.5){
fs.writeFileSync('./db', newAmount)
response.setHeader('Content-Type','application/javascript')
response.statusCode = 200
response.write(`alert('hehe')
amount.innerText = amount.innerText-1
`)
}
else{
response.statusCode = 400
response.write('fail')
}
response.end()
}
这样就可以不用使用 一张图片了,更加节省性能了
但是人们发现一件事,就是说如果成功了的话返回的script标签每次都会执行,所以就不用监听onload事件了,只需要监听onerror就可以了
优化
有人发现你不停的发送script请求,导致HTML里的script标签太多,怎么办,请求过后立即删除!
script.onload = function (e) {
e.currentTarget.remove()
}
script.onerror = function (e) {
alert('fail')
e.currentTarget.remove()
}
server rendered javascript 无刷新局部更新界面
get 请求不安全,如果没有防护措施,任何人都可以用一张图片,一个script标签去伪造请求,所以涉及到金钱等请求必须要用post
一个网站访问另一个网站的script
创建端口: PORT=8002 node server
修改hosts:
127.0.0.1 frank.com
127.0.0.1 jack.com
windows修改hosts
开启两个端口,一个8001,一个8002
用frank的前端访问Jack的后端
但是问题又来了
要解耦,服务端就执行你前端url里送过来的参数,函数在HTML中
window.yyy = function (result) {
if (result === 'success') {
amount.innerText = amount.innerText - 1;
} else {
}
}
button.onclick = function () {
let script = document.createElement('script')
script.src = 'http://jack.com:8002/pay?callbackName=yyy'
函数名包含在url中传输,callbackName 函数已经在前端写好了,这
就解耦了,后端只要确认你执行哪个函数就行
document.body.appendChild(script)
script.onload = function (e) {
e.currentTarget.remove()
}
script.onerror = function (e) {
alert('fail')
e.currentTarget.remove()
}
}
response.write(`
${query.callbackName}.call(undefined,'{
"success":true,
"left":${newAmount}
}')
`)
什么是JSONP(自己理解)
后端响应前端最重要的就是这一块JSON,也有可能是对象,JSON和前后称为padding的部分合起来就是JSONP
JSON+padding = JSONP
大部分时间不一定是JSON,可能是String
那么就是'StringP'
什么是真正的JSONP
请求方:frank.com的前端程序员(浏览器)
响应方:Jack.com的后端程序员(服务器)
1.请求创建script,src指向响应方,同时传一个查询参数?callbackName=yyy
2.响应方根据查询参数callbackName,构造形如
1.yyy.call(undefined,'你要的数据')
2.yyy('你要的数据')
这样的响应
3.浏览器接到这样的响应,就会执行yyy.call(undefined,'你要的数据')
4.那么请求方就会知道了自己想要的数据
这就是JSONP
有两条规定:
1.回调callbackName统一规定为callback
2.函数名称为了不冲突覆盖 yyy改为随机数,例如frank123568454()
真正的JSONP写法
前台代码
button.onclick = function () {
let script = document.createElement('script')
let functionName = 'frank' + parseInt(Math.random() * 1000000, 10)
window[functionName] = function (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) {
e.currentTarget.remove()
delete window[functionName]
}
script.onerror = function (e) {
alert('fail')
e.currentTarget.remove()
delete window[functionName]
}
}
后台代码
var amount = fs.readFileSync('./db', 'utf8') //同步读一个文件
var newAmount = amount - 1
fs.writeFileSync('./db', newAmount)
response.setHeader('Content-Type', 'application/javascript')
response.statusCode = 200
response.write(`
${query.callback}.call(undefined,'{
"success":true,
"left":${newAmount}
}')
`)
//说明jack的后端要对frank的前端代码细节要很熟悉
//解耦
response.end()
jquery jsonp使用方式
$.ajax({
url: "http://jack.com:8002/pay",
dataType: "jsonp",
success: function (response) {
if (response === 'success') {
amount.innerText = amount.innerText - 1;
}
}
})
jquery帮忙省了很多工作,比如callback自动生成,函数名自动生成,但是一个很坑的地方在于JSONP跟AJAX一点关系都没有,它却把jsonp使用归结到了ajax方法了
千万记住这两者不同
面试题:请问jsonp为什么不支持post???
因为jsonp是通过动态创建script实现的,动态创建script的时候只能使用get不能使用post!!
同源策略:域名相同,协议相同,端口相同
AJAX默认的是同源策略,有三种方法实现跨域1.JSONP2.WebSocket3.CROS