是为了解决两个网站之间进行交流的问题
通过 script 标签来发送请求, 因为 script 标签不受域名的限制, 而 Ajax 受限制, 在末尾加上一段参数来表示要执行的方法
请求方: xujinjun.com 的前端程序员 (浏览器)
响应方: jack.com 的后端程序员 (服务器)
请求方创建 script,src 指向响应方, 同时传一个查询参数 ?callback===yyy
响应方根据查询参数 callback, 构造形如
- yyy.call(undefined, '你要的数据')
- yyy('你要的数据')
这样的响应
浏览器收到响应, 就会执行 yyy.call(undefined, '你要的数据')
那么请求方就知道了他要的数据
yyy 一般是随机数
2. JSONP 为什么不支持 POST
因为 JSONP 是通过动态创建 script 来创建的
动态创建 script 的时候只能用 get, 没有办法用 post
3. 代码实现两网站之间的 JSONP 请求
- server.JS (服务器)
- 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 === '/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
- if (Math.random()> 0.5) {
- fs.writeFileSync('./db', newAmount)
- response.setHeader('Content-Type', 'application/javascript')
- response.statusCode = 200
- response.write(`
- ${query.callback}.call(undefined, 'success')
- `)
- response.end()
- } 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()
- }
- index.HTML (浏览器)
- button.addEventListener('click', (e) => {
- let script = document.createElement('script')
- let functionName = 'xujinjun' + parseInt(Math.random()*10000, 10)
- Windows[functionName] = function (result) {
- if (result === 'success') {
- 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 Windows[functionName]
- }
- script.onerror = function () {
- alert('fail')
- e.currentTarget.remove()
- delete Windows[functionName]
- }
- })
来源: http://www.jianshu.com/p/cda7798e96bc