JSONP跨域总结和实践

同源策略

ajax的出现虽然促进了web的发展,但是也带来了安全性方面的问题。

比如我们可以通过xxs将脚本注入到目标网页中,实时的向我们的服务器发送用户的所有操作。

为了保证前端的安全性,推出了同源策略,即无法通过xhr向其他服务器发送信息。

下面是node服务端代码,作为一个简单的http静态服务器。

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

var MIME = {

    "css": "text/css","gif": "image/gif","html": "text/html","ico": "image/x-icon","jpeg": "image/jpeg","jpg": "image/jpeg","js": "text/javascript","json": "application/json","pdf": "application/pdf","png": "image/png","svg": "image/svg+xml","swf": "application/x-shockwave-flash","tiff": "image/tiff","txt": "text/plain","wav": "audio/x-wav","wma": "audio/x-ms-wma","wmv": "video/x-ms-wmv","xml": "text/xml"

}

var routeHandle = {};

function route(handle,pathname,request,response) {
    // path.extname(relPath) 获取文件后缀名
    if (path.extname(pathname)) {
        // 静态文件 处理
        doStaticFile(pathname,response);
    }
    else {
        // action 处理
        response.writeHead(200,{ 'Content-Type': 'text/plain;charset=utf-8' });
        response.write("成功");
        response.end();
    }
}

function doStaticFile(relPath,response) {
    relPath = relPath.indexOf('/') == 0 ? relPath.replace('/','') : relPath;
    fs.exists(relPath,function (exists) {
        if (!exists) {
            response.writeHead(404,{ 'Content-Type': 'text/plain;;charset=utf-8' });

            response.write("请求的路径不存在:" + relPath);

            response.end();
        } else {
            fs.readFile(relPath,'binary',function (err,file) {
                if (err) {
                    // 服务器异常
                    response.writeHead(500,{ 'Content-Type': 'text/plain;;charset=utf-8' });

                    response.end();
                } else {
                    // 返回静态文件
                    var suffix = path.extname(relPath);

                    // 由于extname返回值包含”.”,所以通过slice方法来剔除掉”.”
                    var mime = MIME[suffix.slice(1)] || 'text/plain';

                    response.writeHead(200,{ 'Content-Type': mime });

                    response.write(file,"binary");

                    response.end();
                }
            })
        }
    })

}

http.createServer(function (request,response) {

    var pathname = url.parse(request.url).pathname;

    route(routeHandle,response);

}).listen(10000,'127.0.0.1');

下面是客户端的测试代码

<!DOCTYPE html>
<html lang="en">
<head>
    <Meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script> var orderHost = "http://127.0.0.1:10000"; var request = new XMLHttpRequest(); request.open("get",orderHost+"/test",true); request.onreadystatechange = function(){ if(request.readyState == 4){ console.log(request); } } request.send(null); </script>
</body>
</html>

浏览器通过 http://127.0.0.1:10000/index.html 访问

访问成功,这次试下 http://localhost:10000/index.html

非常好,成功触发同源策略。

jsonP跨域

同源策略限制的是xhr请求,对标签(script、img、link等)并没有限制。

jsonP跨域通过script标签的src来实现跨域。

利用script标签的自执行特点,在服务端生成js代码调用客户端传来的回调函数,将数据传入进去。

var querystring = require('querystring');
...

function route(handle,{ 'Content-Type': 'text/javascript;charset=utf-8' });
        var query = url.parse(request.url).query;
        var param = querystring.parse(query); // 序列化成对象

        var data = {
            say: '跨域成功'
        }

        // 回调方法
        response.write(
            '(function(){'
            + param['callback'] + '(' + JSON.stringify(data) + ')'
            + '})()'
            );
        response.end();
    }
}

客户端

<!DOCTYPE html>
<html lang="en">

<head>
    <Meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <script> var orderHost = "http://127.0.0.1:10000"; var script = document.createElement("script"); script.src = orderHost+"/test?callback=testFn"; function testFn(data){ console.log(data.say); } document.getElementsByTagName("head")[0].appendChild(script); </script>
</body>

</html>

最终结果,成功实现跨域。

相关文章

AJAX是一种基于JavaScript和XML的技术,能够使网页实现异步交...
在网页开发中,我们常常需要通过Ajax从后端获取数据并在页面...
在前端开发中,经常需要循环JSON对象数组进行数据操作。使用...
AJAX(Asynchronous JavaScript and XML)是一种用于创建 We...
AJAX技术被广泛应用于现代Web开发,它可以在无需重新加载页面...
Ajax是一种通过JavaScript和HTTP请求交互的技术,可以实现无...