我的笔记,暂时没有附带源代码,见谅。
第一部分阐述什么是JSONP,附带面试题一个。
第二部分是发展历程,img法,script法,JSONP法。没有源代码阅读会笔记困难,再次见谅。
第三部分随笔记录一些基础知识。javascript
请求方:frank.com 的前端程序员(浏览器)
响应方:jack.com 的后端程序员(服务器)html
这就是 JSONP
约定:前端
请问JSONP为何不能发POST请求?
第一句话: 由于JSONP是经过动态建立script实现的。
第二句话: 动态建立script的时候只能用GET,不能用POSTjava
button.addEventLister('click', (e)=>{
let image = document.creatElement('img')
img.src = '/pay'
image.onload = function(){ // 状态码是 200~299 则表示成功
alert('打钱成功')
amount.innerText = amount.innerText - 1
}
image.onerror = function(){ // 状态码大于等于 400 则表示失败
alert('打钱失败')
}
})
复制代码
<script>
button.addEventLister('click', (e)=>{
let script = document.creatElement('script')
script.src = '/apy'
// 只这样作是不行的。必须把下句代码放在body里才能够,不能放在js文件
// 只有把下句代码放在页面里,浏览器才会发请求
document.body.appenChild(script)
script.onerror = function(){
alert('打钱失败')
}
})
</script>
index.js:
response.write(`amount.innerText = amount.innerText - 1`)
复制代码
可是每次打钱成功都会建立一个script,html就变的很丑,因此咱们要打钱成功或失败后删除这个动态建立的script:node
//只需监听script的onload和onerror,都删除这个script便可
script.onload = function(){
e.currentTarget.remove()
}
script.onerror = function(){
alert('打钱失败')
e.currentTarget.remove()
}
复制代码
script请求法过程描述:jquery
若用户点击了打钱的按钮,就建立一个script,script的src就是要请求的路径,而后把script放到页面里,这样浏
览器就会去发起这个路径的get请求;若是get成功了,它首先会执行服务器返回的js的响应,这个响应就是操做页面局
部的刷新,为何会把响应当成script执行呢?一是由于咱们设置的response.setHeader就是application/java
script;二是我前端确实把它放在script标签里的。执行以后,用户就看到金额减小了,减小以后咱们就去监听,
不管成功失败,都会删除这个script。
复制代码
若是A网站的程序员要去调用B网站的JS,就必须对B网站的页面细节知道的很清楚,不然接口就对不上,这样耦合太大了!因此咱们要解除耦合!程序员
方法:我调用个函数就好了,我不关内心面是什么面试
response.write(`amount.innerText = amount.innerText - 1`)
改为
response.write(`xxx.call(undefined,'打钱成功'`)
同时在A网站JS里,监听xxx函数。
复制代码
这个函数名xxx双方是怎么传递的呢?ajax
A:script.src='http://B.com/pay?callback=xxx'
B:response.write(`$(query.callback).call(undefined,'打钱成功'`)
复制代码
代码细节1: json
请求方:frank.com 的前端程序员(浏览器)
响应方:jack.com 的后端程序员(服务器)
这就是 JSONP
约定:
functionName = 'om'+parseInt(Math.random()*100000,10)
window[functionName] = function(result){...}
script.src = 'http://jack.com:8002/pay?callback=' + functionName
复制代码
JSONP
button.addEventListener('click', (e)=>{
let script = document.createElement('script')
let functionName = 'frank'+ parseInt(Math.random()*10000000 ,10)
window[functionName] = function(){ // 每次请求以前搞出一个随机的函数
amount.innerText = amount.innerText - 0 - 1
}
script.src = '/pay?callback=' + functionName
document.body.appendChild(script)
script.onload = function(e){ // 状态码是 200~299 则表示成功
e.currentTarget.remove()
delete window[functionName] // 请求完了就干掉这个随机函数
}
script.onerror = function(e){ // 状态码大于等于 400 则表示失败
e.currentTarget.remove()
delete window[functionName] // 请求完了就干掉这个随机函数
}
})
复制代码
//后端代码
...
if (path === '/pay'){
let amount = fs.readFileSync('./db', 'utf8')
amount -= 1
fs.writeFileSync('./db', amount)
let callbackName = query.callback
response.setHeader('Content-Type', 'application/javascript')
response.write(`
${callbackName}.call(undefined, 'success')
`)
response.end()
}
复制代码
button.addEventListener('click', (e)=>{
$.ajax({ // 这个名字跟ajax没有半毛钱关系,ajax是ajax,jsonp是jsonp
url: "http://jack.com:8002/pay",
dataType: "jsonp",
success: function( response ) {
if(response === 'success'){
amount.innerText = amount.innerText - 1
}
}
})
$.jsonp()
})
复制代码
请问JSONP为何不能发POST请求?
第一句话: 由于JSONP是经过动态建立script实现的。
第二句话: 动态建立script的时候只能用GET,不能用POST
response.setHeader('Content-Type', 'text/html');
&&&amount&&&
这是一个特殊的占位符,总体都是,为了表示这是个人占位符,别人别碰。fs
是filesystem
的缩写,该模块提供本地文件的读写能力,基本上是POSIX文件操做命令的简单包装。可是,这个模块几乎对全部操做提供异步和同步两种操做方式,供开发者选择。 FS讲义 FS文档异步 fs.readFile(文件的路径, 读取完成后的回调函数)
同步 fs.readFileSync(文件路径,'utf8')
fs.readFileSync()的第二个参数能够是一个表示配置的对象,也能够是一个表示文本文件编码的字符串。
默认的配置对象是{ encoding: null, flag: 'r' },即文件编码默认为null,读取模式默认为r(只读)。
若是第二个参数不指定编码(encoding),readFileSync方法返回一个Buffer实例,不然返回的是一个字符串。
Buffer对象是Node处理二进制数据的一个接口,它是Node原生提供的全局对象,能够直接使用。
buffer文档:https://javascript.ruanyifeng.com/nodejs/buffer.html
复制代码
action="URL" 规定当提交表单时向何处发送表单数据。
method="get/post" 规定用于发送 form-data 的 HTTP 方法。
target="" 规定在何处打开 action URL。
复制代码
value="xxx" 规定input元素的值是xxx