同源策略
现在所有支持JavaScript的浏览器都会使用同源策略。
所谓同源是指,域名,协议,端口相同。
解决这种同源策略的方法称之为跨域,跨域的方法有很多种,jsonp跨域是最经典的一种。
JSONP
JSONP是JSON with Padding的略称。它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。
JSONP实现 -- CallBack
创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。
简单实现
fe.html
<script>
function jsonP (option) {
const { url, callback } = option
return new Promise((resolve, reject) => {
let methodName = 'abc'
window[methodName] = function (data) {
resolve(data)
console.log('window')
// 删除
delete window[methodName]
document.body.removeChild(scriptNode)
}
// 生成script
let scriptNode = document.createElement('script')
scriptNode.src = `${url}?${callback}=${methodName}`
// http://localhost:3002/api/books?getBook=abc
console.log(`${url}?${callback}=${methodName}`)
document.body.appendChild(scriptNode)
// 失败
scriptNode.onerror = function () {
reject('error')
}
})
}
// 跨域
jsonP({
url: 'http://localhost:3002/api/books',
callback: 'getBook'
}).then(res => {
console.log('---------',res)
})
</script>
node.js
const http = require('http')
http.createServer((req, res) => {
const url = require('url').parse(req.url)
if (url.pathname === '/api/books') {
// url.query getBook=abc
console.log('url.query', url.query)
const methodName = url.query && url.query.split('=')[1]
// methodName abc
console.log('methodName', methodName)
let list = [{name: 'book1', price: 33}]
// abc([{"name":"book1","price":33}])
console.log(`${methodName}(${JSON.stringify(list)})`)
res.end(`${methodName}(${JSON.stringify(list)})`)
}
}).listen(3002, () => {
console.log('server is running http://localhost:3002')
})