JSONP使用动态创建script实现的,动态创建script只能使用GET不能使用POST。
用 form 可以发请求,但是会刷新页面或新开页面
用 a 可以发 get 请求,但是也会刷新页面或新开页面
用 img 可以发 get 请求,但是只能以图片的形式展示
用 link 可以发 get 请求,但是只能以 CSS、favicon 的形式展示
用 script 可以发 get 请求,但是只能以脚本的形式运行
JSONP
请求方:xxx.com 的前端程序员(浏览器)
响应方:yyy.com 的后端程序员(服务器)
请求方创建 script,src 指向响应方,同时传一个查询参数 ?callbackName=yyy
响应方根据查询参数callbackName,构造形如
yyy.call(undefined, '你要的数据')
yyy('你要的数据')
这样的响应
浏览器接收到响应,就会执行 yyy.call(undefined, '你要的数据')
那么请求方就知道了他要的数据
一个用script标签更新页面信息的方法
node.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 path = request.url
var query = ''
if(path.indexOf('?') >= 0){ query = path.substring(path.indexOf('?')) }
var pathNoQuery = parsedUrl.pathname
var queryObject = parsedUrl.query
var method = request.method
console.log('HTTP 路径为\n' + path)
if(path == '/'){
var string = fs.readFileSync('./index.html','utf8')
var amount = fs.readFileSync('./db','utf8')
string = string.replace('&&amount&&',amount)
response.setHeader('Content-Type', 'text/html; charset=utf-8')
response.write(string)
response.end()
}else if(path === '/pay'){
var amount = fs.readFileSync('./db','utf8')
var newAmount = amount - 1;
fs.writeFileSync('./db',newAmount)
response.setHeader('Content-Type', 'application/javascript')
response.statuseCode = 200;
response.write(`alert('success')
amount.innerText = amount.innerText - 1
`)
response.end()
}else{
response.statusCode = 404
response.write('找不到对应路径')
response.end()
}
})
server.listen(port)
console.log('监听 ' + port + ' 成功\n请用在空中转体720度然后用电饭煲打开 http://localhost:' + port)
前端页面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>nodejs-test</title>
</head>
<body>
<p>您的余额:<span id='amount'>&&amount&&</span></p>
<input type='text' name='number' value='1'>
<input type='submit' value='付款一元' id='button'>
<script>
button.addEventListener('click',(e)=>{
let script = document.createElement('script')
script.src='/pay'
document.body.appendChild(script)
script.onload = function(e){
e.currentTarget.remove()
}
script.onerror = function(){
alert('fail')
e.currentTarget.remove()
}
})
</script>
</body>
</html>
jsonp
node.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 path = request.url
var query = parsedUrl.query
var pathNoQuery = parsedUrl.pathname
var queryObject = parsedUrl.query
var method = request.method
console.log('HTTP 路径为\n' + path)
if(path == '/style.css'){
response.setHeader('Content-Type', 'text/css; charset=utf-8')
response.write('body{background-color: #ddd;}h1{color: red;}')
response.end()
}else if(path == '/main.js'){
response.setHeader('Content-Type', 'text/javascript; charset=utf-8')
response.write('alert("这是JS执行的")')
response.end()
}else if(path == '/'){
var string = fs.readFileSync('./index.html','utf8')
var amount = fs.readFileSync('./db','utf8')
string = string.replace('&&amount&&',amount)
response.setHeader('Content-Type', 'text/html; charset=utf-8')
response.write(string)
response.end()
}else if(pathNoQuery === '/pay'){
var amount = fs.readFileSync('./db','utf8')
var newAmount = amount - 1;
fs.writeFileSync('./db',newAmount)
response.setHeader('Content-Type', 'application/javascript')
response.statuseCode = 200;
response.write(`
${query.callback}.call(undefined,'success')
`)
response.end()
}else{
response.statusCode = 404
response.write('找不到对应路径')
response.end()
}
})
server.listen(port)
console.log('监听 ' + port + ' 成功\n请用在空中转体720度然后用电饭煲打开 http://localhost:' + port)
前端页面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>nodejs-test</title>
</head>
<body>
<p>您的余额:<span id='amount'>&&amount&&</span></p>
<input type='text' name='number' value='1'>
<input type='submit' value='付款一元' id='button'>
<script>
button.addEventListener('click',(e)=>{
let fnName = 'xxx' + parseInt(Math.random()*100000)
window[fnName] = function(result){
alert('nikandaole')
alert(`wodedaodejieguoshi${result}`)
amount.innerText = amount.innerText - 1
}
let script = document.createElement('script')
script.src='/pay?callback=' + fnName
document.body.appendChild(script)
script.onload = function(e){
e.currentTarget.remove()
}
script.onerror = function(){
alert('fail')
e.currentTarget.remove()
}
})
</script>
</body>
</html>
使用jquery jsonp
$.ajax({
url: "http://test.com/pay",
dataType: "jsonp",
jsonp: "callback",
success: function( response ) {
amount.innerText = amount.innerText - 1
}
})
网友评论