同源策略和解决跨域问题

同源策略和解决跨域问题


===================******===================

                            一、同源策略

                            二、错误问题

                                    1、解决方式一

                                    2、解决方式二

                            三、优化

                            四、jQuery对JSONP的实现

                            五、示例

===================******===================

一、同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,
则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。


同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。
所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页
执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。


二、错误问题


A项目(127.0.0.1:8000)
	index.html   #1、 发送Ajax请求 http://127.0.0.1:8011/user/
		   #3、 浏览器检测到B项目返回数据,由于浏览器安全机制同源策略,既协议,IP,端口需要相同,发现index和响应不同源,报错(CORS)


B项目(127.0.0.1:8011) 
	index_view() #2、 视图处理A项目请求,返回数据({'name':'luo','pwd':'123'})

    1、解决方式一

  B项目在返回数据时,给响应头加上
	       response['Access-Control-Allow-Origin'] = "*"  #加上这句就行
        response['Access-Control-Allow-Headers'] = 'content-type'
        response['Access-Control-Allow-Methods'] = '*'

    2、解决方式二

        使用jsonp, 原名 jsonPadding, 原理是通过script标签的跨域特性来绕过同源策略。

        JSONP 一定是GET请求,回调函数设置在url上 --> http:://127.0.0.1:8081/user/?callbacks=SayHi 

方式一:
	jsonp: 'callbacks'就是定义一个存放回调函数的键,jsonpCallback是前端定义好的回调函数方法名'SayHi',
	server端接受callbacks键对应值后就可以在其中填充数据打包返回了; 
		<button οnclick="f()">sendAjax</button>
		<script>
		    function f(){
		          $.ajax({
		                url:"http://127.0.0.1:7766/SendAjax/",
		                dataType:"jsonp",
		                jsonp: 'callbacks',
		                jsonpCallback:"SayHi" # 定义
		           });
		       }
		    function SayHi(arg){
		                alert(arg);
		            }
		</script>

		#后端设置
		def ajax_send2(request):
		    import json  
			callbacks=request.GET.get("callbacks")   #注意要在服务端得到回调函数名的名字
		    s = {"name":"luo","age":18}
		    return HttpResponse("%s('%s')"%(callbacks,json.dumps(dic))) 
 
方式二:
	jsonpCallback参数可以不定义,jquery会自动定义一个随机名发过去,
	那前端就得用回调函数来处理对应数据了。利用jQuery可以很方便的实现JSONP来进行跨域访问。
		<script>
		    function f(){
		            $.ajax({
		               url:"http://127.0.0.1:7766/SendAjax/",
		               dataType:"jsonp",            //必须有,告诉server,这次访问要的是一个jsonp的结果。
		               jsonp: 'callbacks',          //jQuery帮助随机生成的:callbacks="wner"
		               success:function(data){
		                   alert("hi "+data)
		              }
		         });
		       }
		</script>

但是以上的方式也有不足。一般情况下,我们希望这个script标签能够动态的调用,
而不是像上面因为固定在html里面所以没等页面显示就执行了,很不灵活。我们可以通过javascript动态的创建script标签,
这样我们就可以灵活调用远程服务了。来看下面的优化

三、优化

===========================jQuery实现=====================
	<script>
	    #{创建一个script标签,让他请求一次,请求完了删除他#}
	    //动态生成一个script标签,直接可以定义个函数,放在函数里面
	    function add_script(url) {
	        var ele_script = $("<script>");
	        ele_script.attr("src",url);
	        ele_script.attr("id","script");
	        $("body").append(ele_script);
	        $("#script").remove()
	    }

	    function xxx(name){
	        alert("hello"+name)
	    }

	    $(".kuayu").click(function () {
	       add_script("http://127.0.0.1:8080/ajax_send2/?callbacks=xxx")
	    });

	</script>

==================js实现==========================
	<button οnclick="f()">sendAjax</button>

	<script>
	    function addScriptTag(src){
	         var script = document.createElement('script');
	         script.setAttribute("type","text/javascript");
	         script.src = src;
	         document.body.appendChild(script);
	         document.body.removeChild(script);
	    }

	    function func(name){
	        alert("hello"+name)
	    }

	    function f(){
	         addScriptTag("http://127.0.0.1:7766/SendAjax/")
	    }
	</script>

四、jQuery对JSONP的实现

        getJSON实现:

            jQuery框架也当然支持JSONP,可以使用$.getJSON(url,[data],[callback])方法

<button οnclick="f()">sendAjax</button>
<script>
    function f(){
          $.getJSON("http://127.0.0.1:7766/SendAjax/?callbacks=?",function(arg){
            alert("hello"+arg)
        });  匿名函数
    }
</script>
注意:在url的后面必须添加一个callbacks参数,这样getJSON方法才会知道是用JSONP方式去访问服务,
     callbacks后面的那个?是内部自动生成的一个回调函数名

五、示例

// 跨域请求实例
$(".jiangxiTV").click(function () {

    $.ajax({
        url:"http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403",
         dataType: 'jsonp',
         jsonp: 'callback',
         jsonpCallback: 'list',
         success:function (data) {
             console.log(data.data);   //  [{},{},{},{},{},{}]
             week_list=data.data;
             
             $.each(week_list,function (i,j) {
                 console.log(i,j);  // 1 {week: "周一", list: Array(19)}
                 s="<p>"+j.week+"列表</p>";
                 $(".show_list").append(s);

                 $.each(j.list,function (k,v) {  // {time: "0030", name: "通宵剧场六集连播", link: "http://www.jxntv.cn/live/jxtv2.shtml"}
                      a="<p><a href='"+v.link+"'>"+v.name+"</a></p>";
                      $(".show_list").append(a);
                 })
             })
             
         }
    })


})





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值