zoukankan      html  css  js  c++  java
  • 跨域解决方案 (含header、cookie跨域)

    知识小结:

    1.跨域的问题不是服务器的问题,是浏览器不允许跨域 从而报错。

    2.协议  ip  端口,只要其中一个前后端不同,浏览器都视为跨域。

    3.只有X-Requested-With为XMLHttpRequest的情况下才会发生跨域的问题。 而$.get  $.post  $.ajax都是XMLHttpRequest的类型,所以产生跨域问题。getJsonP就是通过绕过这个类型来解决跨域的问题的。

    4.Cookie跨域:不能由前端跨域设置,例如如果页面时127.0.0.1,无法再127.0.0.1的页面向localhost植入Cookie。只能在localhost本域注入Cookie,127.0.0.1可以跨域传输localhost的Cookie给后端(后端也是localhost域)。因此跨域Cookie的植入一般由后端完成。

    解决方案

    5.为了安全,建议由后端植入Cookie,并且设置为HttpOnly。以防止脚本操纵核心Cookie

    6.非简单请求,会发送OPTIONS预检命令,看是否支持某些字段的修改,例如自定义Header,自定义Content-Type等。发送预检命令的时间由Access-Control-Max-Age来定,单位为秒。

    跨域具体方案:

    1. 让后台修改,支持某些前端域名的跨域。php代码如下:

         header('Access-Control-Allow-Origin:*'); //支持所有前端域名,但是*有个问题,就是不支持Cookie的跨域

         也可以动态设置跨域。header('Access-Control-Allow-Origin:'.$_SERVER['HTTP_ORIGIN']);//如果请求涉及到跨域,那么origin会自动带上前端域名信息。这样做还有一个好处,可以支持cookie跨域

    2. jsonp。 讲get请求伪装成一个script文件的加载。就可以绕过跨域的问题为了。

                      缺点:需要后台做修改;只能用get方法;发出去的不是xhr请求;

       jquery的jsonp底层实现原理如下:    

    <body>
    <script>
    	function showData (result) {
    		alert(result.message);
    	}
    	$(document).ready(function () {
    		$("#btn").click(function () {
    			$("head").append("<script src='http://localhost/frontpage/test.php?callback=showData'></script>");
    		});
    	});
    </script>
    	<input type='text' id='text' />
    	<button id="btn">btn</button>
    </body>
    </html>
    

      

    <?php
    	header('Content-Type:application/json; charset=utf-8');
    	$output = array(
    					"status"=>-100,
    					"message"=>"返回资讯",
    	        		"data"=>NULL
    				);
    	echo 'showData'.'('.json_encode($output).')';	//post request
    	exit(0);
    

     jsonp的使用如下:

    <script>
    	//function showData (result) {
    	//	alert(result.message+"ddg");
    	//}
    	$(document).ready(function () {
    		$("#btn").click(function () {
    			$.ajax({
    				url: "http://localhost/frontpage/test.php",
    				type: "GET",
    				dataType: "jsonp",  //指定服务器返回的数据类型
    				//jsonpCallback: "showData",  //指定回调函数名称
    				success: function (result) {
    					alert(result.message);
    				}
    			});
    		});
    	});
    </script>
    	<input type='text' id='text' />
    	<button id="btn">btn</button>
    </body>
    </html>
    

      

    <?php
    	header('Content-Type:application/json; charset=utf-8');
    	$output = array(
    					"status"=>-100,
    					"message"=>"返回资讯",
    	        		"data"=>NULL
    				);
    	echo $_GET['callback'].'('.json_encode($output).')';	//post request
    	exit(0);
    

      

    3. 自定义header进行跨域

        自定义的Header跨域可以通过:前端设置Header、后端设置Access-Control-Allow-Headers来解决。

        Cookie跨域,只能通过后端设置(前端配合);不能通过前端直接设置跨域的Cookie。

        简单请求不会触发OPTIONS命令,非简单请求会触发OPTIONS,可以通过MAX-AGE设置触发OPTIONS的间隔。

        简单请求和非简单请求可以参看百度。

    $.ajax({
    	url: 'http://localhost/frontpage/test.php',
    	type: 'POST',//or GET DELETE PUT
    	cache:false,//务必false,某些浏览器如果不是false,会有缓存
    	
         //注意新增请求头,会首先调用OPTIONS方法,来看后端是否支持。
    	headers:{//添加头方法1
    		"h1":"yes1",
    		"h2":"yes2",
    		//"cookie":"my1=3bc"
    	},
    	beforeSend:function(xhr){//添加头方法二,可以设置header,cookie
        		xhr.setRequestHeader("h3",34444);
    		xhr.setRequestHeader("h4",34444);
        		//xhr.setRequestHeader("af2","34444");
        		//$.cookie('yy', 4446664444, { expires: 7,path: '/',domain:'other_domain'  });//前端跨域设置,无效果。只能在other_domain本域设置。
       	},
    	xhrFields:{//
    		withCredentials:true//允许前端把跨域的Cookie带给后端[允许后端向前端植入cookie]。是被调用方域名的cookie
    	},
         data: {'title':'test334'},
    	success: function(response){
    		console.log(response.status)
    $.cookie("token",response.data,{expires:7,path:'/'});
    location.href='index.html'; }, complete: function(XMLHttpRequest, textStatus,a,b,c,ed,f){ console.log(textStatus); }, error: function(XMLHttpRequest, textStatus, errorThrown){ console.log("dg"); //通常情况下textStatus和errorThrown只有其中一个包含信息 //this; //调用本次ajax请求时传递的options参数 } });

      

    <?php
    	header('Content-Type:application/json; charset=utf-8');//设置返回格式
    	//header('Access-Control-Allow-Headers:h1,h2,h3,h4');//支持自定义的header 
    	header('Access-Control-Allow-Origin:'.$_SERVER['HTTP_ORIGIN']);//动态支持跨域
    	header("Access-Control-Allow-Credentials:true");///支持cookie额跨域,允许后端跨域设置Cookie。
    	//setCookie("name","value");
    	
    	if($_SERVER["REQUEST_METHOD"]=="OPTIONS"){
    		header("Access-Control-Max-Age: 5");//设置预检请求的有效期,单位是秒【OPTION】。
    		header('Access-Control-Allow-Headers:'.$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']);//支持自定义的header
    		exit(0);
    	}
    	$output = array(
    			"status"=>-100,
    			"message"=>"返回资讯",
    	             "data"=>$_SERVER
    		);
    	//echo $_GET['callback'].'('.json_encode($output).')';	//post request
    	echo json_encode($output);	//post request
    	exit(0);
    

      

  • 相关阅读:
    【LDAP】LDAP 中 CN, OU, DC 的含义
    【LDAP】LDAP介绍
    【LDAP】Openldap导入数据
    【LDAP】LDAP常用命令解析
    【Linux】debian 7 安装 rz sz lrzsz
    【Linux】Debian 8 设置命令行界面的文本颜色
    【Linux】Debian vim没有颜色的解决办法
    【计算机网络】一步一步学习IP路由流程
    【密码学】RSA密钥长度、明文长度和密文长度
    【密码学】CSP的概念
  • 原文地址:https://www.cnblogs.com/dongfangchun/p/9372109.html
Copyright © 2011-2022 走看看