JSONP跨域总结和实践

前端之家收集整理的这篇文章主要介绍了JSONP跨域总结和实践前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

同源策略

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

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

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

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

  1. var http = require("http");
  2. var url = require('url');
  3. var path = require('path');
  4. var fs = require('fs');
  5.  
  6. var MIME = {
  7.  
  8. "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"
  9.  
  10. }
  11.  
  12. var routeHandle = {};
  13.  
  14. function route(handle,pathname,request,response) {
  15. // path.extname(relPath) 获取文件后缀名
  16. if (path.extname(pathname)) {
  17. // 静态文件 处理
  18. doStaticFile(pathname,response);
  19. }
  20. else {
  21. // action 处理
  22. response.writeHead(200,{ 'Content-Type': 'text/plain;charset=utf-8' });
  23. response.write("成功");
  24. response.end();
  25. }
  26. }
  27.  
  28. function doStaticFile(relPath,response) {
  29. relPath = relPath.indexOf('/') == 0 ? relPath.replace('/','') : relPath;
  30. fs.exists(relPath,function (exists) {
  31. if (!exists) {
  32. response.writeHead(404,{ 'Content-Type': 'text/plain;;charset=utf-8' });
  33.  
  34. response.write("请求的路径不存在:" + relPath);
  35.  
  36. response.end();
  37. } else {
  38. fs.readFile(relPath,'binary',function (err,file) {
  39. if (err) {
  40. // 服务器异常
  41. response.writeHead(500,{ 'Content-Type': 'text/plain;;charset=utf-8' });
  42.  
  43. response.end();
  44. } else {
  45. // 返回静态文件
  46. var suffix = path.extname(relPath);
  47.  
  48. // 由于extname返回值包含”.”,所以通过slice方法来剔除掉”.”
  49. var mime = MIME[suffix.slice(1)] || 'text/plain';
  50.  
  51. response.writeHead(200,{ 'Content-Type': mime });
  52.  
  53. response.write(file,"binary");
  54.  
  55. response.end();
  56. }
  57. })
  58. }
  59. })
  60.  
  61. }
  62.  
  63. http.createServer(function (request,response) {
  64.  
  65. var pathname = url.parse(request.url).pathname;
  66.  
  67. route(routeHandle,response);
  68.  
  69. }).listen(10000,'127.0.0.1');

下面是客户端的测试代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <Meta charset="UTF-8">
  5. <title>Document</title>
  6. </head>
  7. <body>
  8. <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>
  9. </body>
  10. </html>

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

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

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

jsonP跨域

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

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

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

  1. var querystring = require('querystring');
  2. ...
  3.  
  4. function route(handle,{ 'Content-Type': 'text/javascript;charset=utf-8' });
  5. var query = url.parse(request.url).query;
  6. var param = querystring.parse(query); // 序列化成对象
  7. var data = {
  8. say: '跨域成功'
  9. }
  10. // 回调方法
  11. response.write(
  12. '(function(){'
  13. + param['callback'] + '(' + JSON.stringify(data) + ')'
  14. + '})()'
  15. );
  16. response.end();
  17. }
  18. }

客户端

  1. <!DOCTYPE html>
  2. <html lang="en">
  3.  
  4. <head>
  5. <Meta charset="UTF-8">
  6. <title>Document</title>
  7. </head>
  8.  
  9. <body>
  10. <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>
  11. </body>
  12.  
  13. </html>

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

猜你在找的Json相关文章