• 同源策略引发对跨域jsonp跨域的理解


         一,同源策略其实网络的安全基石,既:http://www.baidu.com:80协议(http或者HTTPS或者ws或者wss)、域名(www.baidu.com)、端口(默认80,可以不写 https默认是443端口)相同。防止一些信息被人盗取或者破坏,具体的概念在这里就不详细述说了,大家可参考阮一峰大师的文章(http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html)。

        二,大家有没有注意下面的这种情况:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    	<style>
    		img{
    			200px;
    			height: 100px;
    		}
    	</style>
    </head>
    <body>
    	<img src="https://mdn.mozillademos.org/files/12676/star.svg" alt="">
    </body>
    </html>
    

      上面代码红色区域src 引用的是https协议下的一个网路图片,但是你把代码在本地浏览器打开的时候,也可以请求到图片,看一下图片的对比。也就是说下面两个链接是在不同域情况下打开的,但是可以跨域请求到想要的图片。也就是说我们可以利用src的属性进行跨域请求数据,也就是说 script标签也可以跨域请求相应的资源,如:<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>

     三,先让大家看代码<!DOCTYPE html>

    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    	<style>
    		img{
    			200px;
    			height: 100px;
    		}
    	</style>
      <script>
         function a(){
          alert(1)
         } </script> </head> <body> <script> a(); </script> </body> </html>

      大家用浏览器打开页面,会看到页面弹出了1,注意看标记为红色的区域。是在两个不同的script一个赋值一个请求,这样是可以请求道的。说这个的目的是为了为下面封装jsonp 做解释。

    四,先看封装好的jsop函数:原理:前端定义个全局的函数,动态创建script,利用src去请求后台的资源,只是后台返回的是一个参数为前端所需数据前端全局函数调用。看下图:请求道的是一个函数的调用。



    下面我对代码里①到⑦做一一的解释。

    ①:cbName是为了跟后台创建一个相应的规则协议,跨域请求的时候,允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,客户端可以随意定制自己的函数(fnName)来自动处理返回数据了。 

    ②:每次请求相同的src浏览器会缓冲,所以在uri后面添加时间戳,防止二次请求的时候,返回不是最新想要的数据。

    ③:url路径不允许带有小数点,由于时间戳带有小数点,要把小数点替换成空。

    ④:src去请求数据时 可以自定义取数据的时间,超过规定的时间,就定义为请求超时。请求超时就不要再让window.fn继续执行处理数据,window[fnName] = null。

    ⑤:跨域请求过来的是自定义的回调函数的调用,当回调调用成功后,也就是调用了全局的window[fnName]函数(这函数里也可以继续回调(success)函数)来处理数据,达到自己想要的数据类型或者舍取。由于获取成功后相应超时的限制意义就不存在了,要把定时器关闭。并把创建好的script对象删除。

    <script>

    fnName (json) {//window下的函数

      ......XXXX

    }

    </script>

    再在动态创建的srcpt里,请求到后台返回数据(数据为:函数的直接调用)。

    <script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=%E7%8E%8B%E6%B5%A9&cb=jsonp_p08777009389580372#"></script>   ===  window.fnName();

    ⑥:拼接url,到达协议的要求,即:后台返回jsonp回调函数的要求:关键字、cbName及其他请求参数。

    ⑦:dom操作创建添加script标签,动态请求数据,成功后直接删除。

    function jsonp(options){
    	if(!options.url){return;}
    	options = options||{};
    	options.data = options.data||{};
    	options.cbName = options.cbName||'cb';//
    	options.timeout = options.timeout||10000;
    	var fnName = 'jsonp_p'+Math.random();//
    	var fnName = fnName.replace('.','');//
    	var timer = setTimeout(function(){//
    		options.error&&options.error();
    		window[fnName] = null;
    	},options.timeout);
    	
    	window[fnName] = function(json){ //
    		options.success&&options.success(json);
    		clearTimeout(timer);
    		document.getElementsByTagName('head')[0].removeChild(oS);
    	};
    	//cb = show
    	options.data[options.cbName] = fnName;
    	var arr = [];
    	for(var name in options.data){//
    		arr.push(name+'='+options.data[name]);
    	}
    	
    	var oS = document.createElement('script');//
    	oS.src = options.url+'?'+arr.join('&');	
    	document.getElementsByTagName('head')[0].appendChild(oS);
    }
    

      五,以上就是本人对jsonp的理解,由于小生才能有限,写的不到位的地方请大神多多指教,本人将不吝赐教,谢谢!

  • 相关阅读:
    MiniGUI
    Android-在XML和Java代码中设置背景在不同状态的效果: <selector>/StateListDrawable
    URLEncoder.encode、URLDecoder.decode、escape、encodeURI、encodeURIComponent
    getDimension,getDimensionPixelOffset和getDimensionPixelSize的一点说明
    Android获取屏幕分辨率及DisplayMetrics简介
    细说Android事件传递机制(dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent)
    Android
    Android坐标
    Android Sqlite IN, NOT IN syntax --- not int (?)
    TextView with SingleLine as true and Gravity as Center not passing the events to the ViewPager if it has a Click Event
  • 原文地址:https://www.cnblogs.com/lixuekui/p/8555746.html
Copyright © 2020-2023  润新知