JSONP实现跨域

什么是JSONP

JSONP的英文全称是 JSON with padding
值得注意的是这里的padding应当译作使用方式,因此JSONP应当译作——JSON的一种使用方式


JSONP的原理

由于同源策略,使得不同源的两个页面之间无法相互访问,然而HTML的script标签是个例外。利用这个特点,我们可以通过script标签来获取其它不同源网页的JSON数据——这种使用方式被称为JSONP
它的核心是绕过浏览器的同源策略


实现JSONP的方式

  1. 比如我们用script标签请求一些数据,假设请求用户定位的信息
<script src="http://http://www.bbwtest.com/users_location.json"></script>

问题在于,script标签会被当成js代码立即执行,但我们需要的是一些数据
所以,此时就需要后端的配合

  1. 我们把script标签改一下,加上一些查询字符串
<script src="http://http://www.bbwtest.com/users_location.json?callback=showData"></script>

原本当后端收到这个请求时,我们希望得到一个{“name”:”bluesbonewong”,”age”:16}这种json类型的数据,但由于script标签会被当做js代码立即执行,所以我们希望后端收到请求后返回一个函数,如

showData({“name”:”bluesbonewong”,”age”:16})

那么此时前端只需要在数据返回前声明一个全局函数showData即可,如

function showData(data){
    return data
}

实现代码

注意修改host文件使得不同域名映射至同一个IP地址,即可测试JSONP跨域


服务端代码

var http = require('http')
var fs = require('fs')
var path = require('path')
var url = require('url')

var server = http.createServer(function (request, response) {
    var pathObj = url.parse(request.url, true)
    console.log(pathObj)

    switch (pathObj.pathname) {
        case '/getdata':
            var data = {"name": "bluesbonewong", "age": 16}
            response.setHeader('content-type', 'text/json;charset=utf-8')
            // 以下是重点
            if (pathObj.query.callback) {
                // 判断查询字符串中是否有callback
                response.end(pathObj.query.callback + '(' + JSON.stringify(data) + ')')
                // 返回一个 showData(JSON.stringify(data)) 函数
                console.log(data)
                // 这里data会被自动转换为对象格式{ name: 'bluesbonewong', age: 16 }双引号会被去除
                // 所以一定要用JSON.stringify()把数据转换为json格式
            } else {
                response.end(data)
            }
            // 以上是重点
            break
        // 以下不用看
        default:
            fs.readFile(path.join(__dirname, pathObj.pathname), function (error, data) {
                if (error) {
                    response.writeHead(404, 'not found')
                    response.end('<h1>not found</h1>')
                } else {
                    response.end(data)
                }
            })
    }
})

console.log('请在浏览器地址栏输入 localhost:8080')
server.listen(8080)

HTML代码

<!doctype html>
<html lang="ch">
<head>
    <meta charset="utf-8">
    <title>使用JSONP跨域</title>
</head>
<body>
<h1>JSONP实现跨域</h1>
<script>
    // JSONP
    function addScript() {
        var script = document.createElement('script')
        script.src = 'http://justfun:8080/getdata?callback=showData'
        document.head.appendChild(script)
        // 添加标签后会立即执行,且在数据到来之前,会阻断其它加载
        document.head.removeChild(script)
        // 移除也没关系,因为数据此时已经拿到
    }

    function showData(data) {
        console.log(data)
    }

    addScript()
    showData()
</script>
</body>
</html>

代码GitHub地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容