您的位置:首页 > Web前端 > HTML

【HTML】常用跨域技术

2015-09-12 21:06 501 查看
什么是跨域

XmlHttpResponse

图像Pingiframe

JSONP

WebSocket

什么是跨域

出于安全方面的考虑,运行在同一浏览器中的框架,标签页,窗口间的通信一直都受到了严格的限制。而现实中存在将不同站点的内同在浏览器上进行交互的需求,这就需要使用**跨域**.


网上列的这个表不错,一目了然:

URL说明是否允许通信
http://www.a.com/a.js http://www.a.com/b.js同一域名下允许
http://www.a.com/lab/a.js http://www.a.com/script/b.js同一域名下不同文件夹允许
http://www.a.com:8000/a.js http://www.a.com/b.js同一域名,不同端口不允许
http://www.a.com/a.js https://www.a.com/b.js同一域名,不同协议不允许
http://www.a.com/a.js http://70.32.92.74/b.js域名和域名对应ip不允许
http://www.a.com/a.js http://script.a.com/b.js主域相同,子域不同不允许
http://www.a.com/a.js http://a.com/b.js同一域名,不同二级域名(同上)不允许(cookie这种情况下也不允许访问)
http://www.cnblogs.com/a.js http://www.a.com/b.js不同域名不允许
注意一下实例需要在server上运行。

常见的几种server都能使用

Tomcat 网址输入:localhost:8080/*.html

Apache 网址输入:localhost:80/*.html

安装有Python的话,CMD/PowerShell在文件目录下输入python -m SimpleHTTPServer 9999,网址输入:localhost:9999/*.html

CORS(Cross-Origin Resource Sharing,跨源资源共享)

1.XmlHttpResponse

Firefox 3.5+、Safari 4+、Chrome、iOS 版Safari 和Android 平台中的WebKit 都通过XMLHttpRequest对象实现了对CORS 的原生支持。在尝试打开不同来源的资源时,无需额外编写代码就可以触发这个行为。要请求位于另一个域中的资源,使用标准的XHR 对象并在open()方法中传入绝对URL 即可

<!DOCTYPE html>
<html>
<head>
<title>Cross-Browser CORS Request Example</title>
</head>
<body>
<p>This example must be run on a server to work properly and will only work in browsers supporting CORS.</p>
<script>

function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){//=====IE
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}

var request = createCORSRequest("get", "http://www.somewhere-else.com/xdr.php");
if (request){
request.onload = function(){
//do something with request.responseText
};
request.send();
}
</script>
</body>
</html>


注:与 IE 中的XDR 对象不同,通过跨域XHR 对象可以访问status 和statusText 属性,而且还支持同步请求。

 不能使用 setRequestHeader()设置自定义头部。

 不能发送和接收cookie。

 调用 getAllResponseHeaders()方法总会返回空字符串。

补充:

CORS 通过一种叫做Preflighted Requests 的透明服务器验证机制支持开发人员使用自定义的头部、GET 或POST 之外的方法,以及不同类型的主体内容。

1.1 预请求(Preflighted Reqeusts)

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/post-here/';
var body = '{C}{C}{C}{C}{C}{C}{C}{C}{C}{C}Arun';

function callOtherDomain(){
if(invocation)
{
invocation.open('POST', url, true);
invocation.setRequestHeader('X-PINGOTHER', 'pingpong');//自定义请求头
invocation.setRequestHeader('Content-Type', 'application/xml');
invocation.onreadystatechange = handler;
invocation.send(body);
}

......


如上,以 XMLHttpRequest 创建了一个 POST 请求,为该请求添加了一个自定义请求头(X-PINGOTHER: pingpong),并指定数据类型为 application/xml。所以,该请求是一个“预请求”形式的跨站请求。

1.2 带凭据的请求

默认情况下,跨源请求不提供凭据(cookie、HTTP 认证及客户端SSL 证明等)。通过将withCredentials 属性设置为true,可以指定某个请求应该发送凭据。如果服务器接受带凭据的请求,会用下面的HTTP 头部来响应。

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';

function callOtherDomain(){
if(invocation) {
invocation.open('GET', url, true);
invocation.withCredentials = true;//使得Cookies可以随着请求发送
invocation.onreadystatechange = handler;
invocation.send();
}


客户端与浏览器端的交互如下:

GET /resources/access-control-with-credentials/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://foo.example/examples/credential.html Origin: http://foo.example Cookie: pageAccess=2

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:34:52 GMT
Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2
X-Powered-By: PHP/5.2.6
Access-Control-Allow-Origin: http://foo.example Access-Control-Allow-Credentials: true
Cache-Control: no-cache
Pragma: no-cache
Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 106
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain


Cookie: pageAccess=2,可以看到有Cookie了。

Access-Control-Allow-Origin: http://foo.example不能为*,否者错误。

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

2.图像Ping/iframe

<script>
var img = new Image();
img.onload = img.onerror = function(){
alert("Done!");
};
img.src = "http://www.example.com/test?name=Nicholas";
</script>


iframe也是用src属性

3.JSONP

<script>
function handleResponse(response){
alert("You're at IP address " + response.ip + ", which is in " + response.city + ", " + response.region_name);
}
var script = document.createElement("script");
script.src = "http://freegeoip.net/json/?callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);
</script>




控制台NetWork



4.WebSocket

由于 Web Sockets 使用了自定义的协议,所以URL 模式也略有不同。未加密的连接不再是http://,而是ws://;加密的连接也不是https://,而是wss://。在使用Web Socket URL 时,必须带着这个模式,因为将来还有可能支持其他模式。

这里我们举一个《HTML5 高级程序设计》书中的例子:

- 使用Python服务器 python -m SimpleHTTPServer 9999。

- 其中websocket服务器在文件夹中websocket.py 通过命令:python websocket.py开启

代码:

<!DOCTYPE html>
<title>WebSocket Test Page</title>
<script>

var log = function(s) {
if (document.readyState !== "complete") {
log.buffer.push(s);
} else {
document.getElementById("output").innerHTML += (s + "\n")
}
}
log.buffer = [];

url = "ws://localhost:8080/echo";
w = new WebSocket(url);
w.onopen = function() {
log("open");
w.send("thank you for accepting this Web Socket request");
}
w.onmessage = function(e) {
log(e.data);
}
w.onclose = function(e) {
log("closed");
}

window.onload = function() {
log(log.buffer.join("\n"));
document.getElementById("sendButton").onclick = function() {
w.send(document.getElementById("inputMessage").value);
}
}
</script>

<input type="text" id="inputMessage" value="Hello, Web Socket!"><button id="sendButton">Send</button>
<pre id="output"></pre>


网址输入:http://localhost:9999/websocket.html

另外还有一些可以参考其他博客:

JavaScript跨域总结与解决办法:

http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HTML-CORS CORS-跨域