var script = document.createElement('script'); script.setAttribute('src',url);
window['funcname'] = function(data){ console.log(data); }
這種形式的函數ajax
script.onload = function(){ delete window['funcname']; script.parentNode.removeChild(script); }
var data = {} res.end( `funcname({ data : ${JSON.stringfy(data)} })` );
如上述所示,jsonp 在使用過程當中須要建立標籤,聲明全局回調函數等繁瑣步驟。本文將 jsonp 的細節封裝在內部,對外暴露回調的接口。使用者無需考慮 dom 操做,更多考慮在業務層上。express
var uuid = function() { var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''), uuid = new Array(36), rnd=0, r; for (var i = 0; i < 36; i++) { if (i==8 || i==13 || i==18 || i==23) { uuid[i] = '-'; } else if (i==14) { uuid[i] = '4'; } else { if (rnd <= 0x02) rnd = 0x2000000 + (Math.random()*0x1000000)|0; r = rnd & 0xf; rnd = rnd >> 4; uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; } } return uuid.join(''); };
var script = document.createElement('script') var callbackFunctionKey = (opts && opts.callback) || 'callback' // 避免污染全局變量 var callbackFunctionName = 'jsonp-' + uuid(); script.setAttribute('src', url + '?' + callbackFunctionKey + '=' + callbackFunctionName) window[callbackFunctionName] = function(data){ callback(data); // clean delete window[callbackFunctionName]; script.parentNode.removeChild(script); }
function Jsonp(url,callback,opts){ var uuid = function() { var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''), uuid = new Array(36), rnd=0, r; for (var i = 0; i < 36; i++) { if (i==8 || i==13 || i==18 || i==23) { uuid[i] = '-'; } else if (i==14) { uuid[i] = '4'; } else { if (rnd <= 0x02) rnd = 0x2000000 + (Math.random()*0x1000000)|0; r = rnd & 0xf; rnd = rnd >> 4; uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; } } return uuid.join(''); }; var script = document.createElement('script') var callbackFunctionKey = (opts && opts.callback) || 'callback' // 避免污染全局變量 var callbackFunctionName = 'jsonp-' + uuid(); script.setAttribute('src', url + '?' + callbackFunctionKey + '=' + callbackFunctionName) window[callbackFunctionName] = function(data){ callback(data); // clean delete window[callbackFunctionName]; script.parentNode.removeChild(script); } document.body.appendChild(script) }
const express = require('express'); const app = express(); app.get('/', function(req, res){ var funcname = req.query['callback']; res.end( ` window['${funcname}']({ data : 'data' }) `); console.log('get'); }) app.listen(3000);