跨域解決方案 (含header、cookie跨域)

知識小結:javascript

1.跨域的問題不是服務器的問題,是瀏覽器不容許跨域 從而報錯。php

2.協議  ip  端口,只要其中一個先後端不一樣,瀏覽器都視爲跨域。html

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的植入通常由後端完成。java

解決方案jquery

5.爲了安全,建議由後端植入Cookie,而且設置爲HttpOnly。以防止腳本操縱核心Cookieajax

6.非簡單請求,會發送OPTIONS預檢命令,看是否支持某些字段的修改,例如自定義Header,自定義Content-Type等。發送預檢命令的時間由Access-Control-Max-Age來定,單位爲秒。json

 

 

 

跨域具體方案:後端

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
	},
     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);
相關文章
相關標籤/搜索