美文网首页
JSONP实现跨域

JSONP实现跨域

作者: Bluesbone | 来源:发表于2017-11-01 23:07 被阅读0次

    什么是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地址

    相关文章

      网友评论

          本文标题:JSONP实现跨域

          本文链接:https://www.haomeiwen.com/subject/fhunpxtx.html