An origin is defined by the scheme, host, and port of a URL. Generally speaking, documents retrieved from distinct origins are isolated from each other.javascript
https://developer.mozilla.org/zh-CN/docs/Same-origin_policy_for_file:_URIsphp
http://www.w3.org/Security/wiki/Same_Origin_Policyhtml
對於一些同源策略, 是HTML5新定義, 是否可以使用,能夠查詢以下網站:html5
http://caniuse.com/java
javascript的同源策略,見以下文章:nginx
https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy?redirectlocale=zh-CN&redirectslug=JavaScript%E7%9A%84%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5 git
只有在 協議 域名 和 端口 徹底一致的狀況下, 才認爲, 兩個頁面對應同一個源。github
下面使用iframe和js api,構造跨域訪問實例。web
js api 爲 iframe.contentDocument, 父親頁面經過此js api訪問iframe內嵌頁面的內容, 詳細見下文:ajax
https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement
父親頁面爲: a.html, 內嵌一個 iframe, 引用b.html(域名爲 localhost)
父親頁面加載後, 訪問內嵌頁面的 ID爲binput 輸入框的值。
<html> <body> <h1> hi, this is a.html, frame below show b.html </h1> <iframe src="http://localhost/b.html"></iframe> <script type="text/javascript"> window.onload = function(){ console.log("a.html loaded"); var frame = document.getElementsByTagName("iframe"); console.log("frame src="+frame[0].src); var binput = frame[0].contentDocument.getElementById("binput"); console.log("b.html binput value="+binput.value); } </script> </body> </html>
<html> <body> <h1> hi, this is b.html. this page call by localhost domain. </h1> <input id="binput" value="binput"/> </body> </html>
實驗結果:
使用http://localhost/a.html訪問, 查看控制檯, 能夠發現 a能夠訪問b的binput。
使用http://127.0.0.1/a.html訪問, 查看控制檯, 能夠發現瀏覽器有報錯, (b.html使用localhost域名訪問),chrome瀏覽器訪問報錯以下:
a.html loaded a.html:9
frame src=http://localhost/b.html a.html:11
Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "http://127.0.0.1" from accessing a frame with origin "http://localhost". Protocols, domains, and ports must match. a.html:12
ajax不能跨域訪問, 同iframe跨域訪問相同, 都是受同源策略影響。
CORS 爲ajax跨域訪問的一種解決方案,詳細見下文:
http://www.cnblogs.com/Darren_code/p/cors.html
CORS W3C規範:
http://www.w3.org/TR/cors/
網上介紹的例子, 可見 ajax 請求跨域,是現到達服務器,而後根據響應來決定是否在客戶端顯示響應的。
http://blog.csdn.net/hfahe/article/details/7730944
服務器: index.php
添加跨域可訪問的 header 頭,能夠任何網站訪問:
<?php header("Access-Control-Allow-Origin:*"); echo "hello ".$_SERVER['HTTP_HOST']; exit; ?> Something is wrong with the XAMPP installation :-(
客戶端: index.html
其中的ajax使用127.0.0.1域名訪問index.php
<html> <head> <style> </style> </head> <body> <h1>hello world!</h1> <input type="text" value="test"/> <input type="button" value="button"/> <script type='text/javascript'> function createCORSRequest(method, url) { var xhr = new XMLHttpRequest(); if ("withCredentials" in xhr) { // 此時即支持CORS的狀況 // 檢查XMLHttpRequest對象是否有「withCredentials」屬性 // 「withCredentials」僅存在於XMLHTTPRequest2對象裏 xhr.open(method, url, true); } else if (typeof XDomainRequest != "undefined") { // 不然檢查是否支持XDomainRequest,IE8和IE9支持 // XDomainRequest僅存在於IE中,是IE用於支持CORS請求的方式 xhr = new XDomainRequest(); xhr.open(method, url); } else { // 不然,瀏覽器不支持CORS xhr = null; } return xhr; } var xhr = createCORSRequest('GET', "http://127.0.0.1/index.php"); if (!xhr) { throw new Error('CORS not supported'); } xhr.onreadystatechange = function processRequest() { if (xhr.readyState == 4) // 判斷對象狀態 { if (xhr.status == 200) // 請求結果已經成功返回 { alert(xhr.responseText); } } }; xhr.send(); </script> </body> </html>
若是頁面使用 http://127.0.0.1/index.html訪問, ajax屬於站內訪問,能夠執行成功,
若是頁面使用 http://localhost/index.html訪問, ajax屬於跨站訪問,執行報錯:
XMLHttpRequest cannot load http://127.0.0.1/index.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin ' http://localhost' is therefore not allowed access.
nginx配置跨域
postMessage
https://developer.mozilla.org/zh-CN/docs/Web/API/window.postMessage
http://www.ibm.com/developerworks/cn/web/1301_jiangjj_html5message/index.html
示例來源用途第二個網址:
服務器localhost/a.php使用postMessage傳送 消息到 內嵌的不一樣域頁面 127.0.0.1/b.php:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Test Cross-domain communication using HTML5</title> <script type="text/JavaScript"> function sendIt(){ // 經過 postMessage 向子窗口發送數據 document.getElementById("otherPage").contentWindow .postMessage( document.getElementById("message").value, "http://127.0.0.1/" ); } </script> </head> <body> <!-- 經過 iframe 嵌入子頁面 --> <iframe src="http://127.0.0.1/b.php" id="otherPage"></iframe> <br/><br/> <input type="text" id="message"><input type="button" value="Send to child.com" onclick="sendIt()" /> </body> </html>
b.php
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Web page from child.com</title> <script type="text/JavaScript"> //event 參數中有 data 屬性,就是父窗口發送過來的數據 window.addEventListener("message", function( event ) { // 把父窗口發送過來的數據顯示在子窗口中 document.getElementById("content").innerHTML+=event.data+"<br/>"; }, false ); </script> </head> <body> Web page from http://127.0.0.1 <div id="content"></div> </body> </html>
使用報文頭標識 : X-Frame-Options
https://developer.mozilla.org/en-US/docs/Web/HTTP/X-Frame-Options
詳細解釋見下面說明:
Using X-Frame-Options
There are three possible values for X-Frame-Options:
DENY
- The page cannot be displayed in a frame, regardless of the site attempting to do so.
SAMEORIGIN
- The page can only be displayed in a frame on the same origin as the page itself.
ALLOW-FROM uri
- The page can only be displayed in a frame on the specified origin.
a.php 內嵌 b.php , 使用locahost引用:
<html> <body> <h1> hi, this is a.php, frame below show b.php using domain localhost </h1> <iframe src="http://localhost/b.php"></iframe> </body> </html>
b.php, 經過頭decalare內嵌權限:
<?php
//header("X-Frame-Options: DENY"); // 無論地址欄訪問 localhost/a.php 仍是 127.0.0.1/a.php,都不能顯示b.php
//header("X-Frame-Options: SAMEORIGIN"); // 只有使用 localhost/a.php,才能能顯示b.php
header("X-Frame-Options: ALLOW-FROM 127.0.0.1"); // 即便使用 127.0.0.1/a.php,也能顯示b.php
?>
<html> <body> <h1> hi, this is b.html. this page call by localhost domain. </h1> <input id="binput" value="binput"/> </body> </html>