跨域
目前控制台的解决办法
console.qcloud.com/sms
sms.qcloud.com
发请求
server.js
net.js
不能使用jsonp来传文件
需要用ajax和form表单
跨域需要在mc层特殊设置
同源策略
什么情况就是同源
同协议、同域名、同端口
1,如果是协议和端口造成的跨域问题“前端”是无能为力的
2:域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。
window.location.protocol +window.location.host
跨域限制
限制1.不能通过ajax的方法去请求不同源中的文档
限制2.浏览器中不同域的框架之间不能进行js的交互操作
跨域的解决办法
JSONP--JSON with Padding
核心是动态添加<script>标签来调用服务器提供的js脚本。
如客户想访问 :
http://example.com/jsonp.php?callback=dosomething
假设客户期望返回JSON数据:
["a","b"]。
真正返回到客户端的数据显示为:
dosomething(["a","b"])。
JSONP--JSON with Padding
a.html
http://example.com/data.php
页面输出:
ajax + CORS
通过xmlHttpRequest获取非本页内容
需要浏览器和服务器同时支持
GET /cors HTTP/1.1
Origin: http://test.com
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。
ajax + CORS
服务器返回的响应头:
Access-Control-Allow-Origin: http://test.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
window.postMessage(H5)
window.postMessage(H5)
需要接收消息的window对象,通过监听自身的message事件来获取传过来的消息,消息内容储存在该事件对象的data属性中
其他
1. 修改document.domain来跨子域
2. 使用window.name + iframe
window.name的值只能是字符串,最大2M
动态创建iframe,src设置和主页面同源
只能把document.domain设置成自身或更高一级的父域,且主域必须相同
用隐藏的iframe做代理,和目标请求同域
3. 使用location.hash + iframe
1) a.html首先创建自动创建一个隐藏的iframe,iframe的src指向test.com域名下的b.html页面
2) b.html响应请求后再将通过修改a.html的hash值来传递数据
3) 同时在a.html上监听location.hash的值有没有变化,一旦有变化则获取获取hash值
JSONP的优缺点
工作原理
1、Ajax直接请求普通文件存在跨域无权限访问的问题;
2、但是,Web页面上调用js文件时则不受是否跨域的影响(拥有"src"这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>);
3、于是,想通过纯web端跨域访问数据,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用;
4、恰巧JSON的纯字符数据格式可以简洁的描述复杂数据;
5、解决方案:web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件。
6、客户端在对JSON文件调用成功之后,也就获得了自己所需的数据。
7、该协议的要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
优点
1. 兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持
2. 可以向不支持CORS的网站请求数据
3. 将回调方法的权限给了调用方,提供服务以后的页面渲染和后续view操作都由调用者来自己定义。如果有两个页面需要渲染同一份数据,你们只需要有不同的渲染逻辑就可以了,逻辑都可以使用同 一个jsonp服务。
缺点
1.它只支持GET请求
2.它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
3.jsonp在调用失败的时候不会返回各种HTTP状态码。
4.缺点是安全性。提供jsonp的服务存在页面注入漏洞,即它返回的javascript的内容被人控制的。所有调用这个 jsonp的网站都会存在漏洞。所以在使用jsonp的时候必须要保证使用的jsonp服务必须是安全可信的。
服务器端的设置
遇到的情况
1.添加允许跨域的头
2.客户端无法携带跨域cookie
3.因为加了withCredentials报文头,可是客户端不知道服务器允不允许报的错
4.由于客户端不知道服务端是否允许POST请求而报的错
ajax请求遇到跨域
ajax请求遇到跨域
抓包发现跳转到了登录页
cookie登录态没有带过去(跨域)
ajax请求
php
HTTP响应首部字段
Access-Control-Allow-Origin 允许访问该资源的外域URI
Access-Control-Expose-Headers 服务端允许的首部字段集合
Access-Control-Max-Age 预检请求的响应有效时间
Access-Control-Allow-Credentials 是否允许credentials标志
Access-Control-Allow-Methods 请求所允许使用的HTTP方法
Access-Control-Allow-Headers 允许携带的首部字段
不能控制服务器的时候怎么办?
异步上传文件并获得返回值(完全跨域)
AJAX可以进行数据的异步请求,但对于文件和跨域问题却束手无策。
Jsonp可以进行跨域数据的异步请求,但同样不能使用于文件。
<form>表单可以进行跨域数据和文件的上传,但却会使页面跳转。
1、将<form>表单提交给一个iframe
2、将<form>的target属性设置为该iframe的name值
3、<form>的action URL就会在这个iframe中打开
4、服务器的返回数据输出到iframe中
5、通过主页面和iframe之间的交互完成对返回数据的读取
解决方案
基本结构(不跨域)
前端:(www.test.com)
<form action="http://www.test.com/io.php" method="POST" enctype="multipart/form-data" target="upload">
<input type="file" name="upload_file" />
<input type="submit" value="开始上传" />
</form>
<iframe name="upload" style="display:none"></iframe>
后台:(www.test.com)
<?php
move_uploaded_file($_FILES['upload_file']['tmp_name'],'upload/' . $_FILES['upload_file']['name']);
echo 'This data is from server!'; //返回数据,这行字将输出到iframe的body中
?>
基本结构(子域不同)
前端:(www.a.test.com)
<form action="http://b.test.com/io.php" method="POST" enctype="multipart/form-data" target="upload">
<input type="file" name="upload_file" />
<input type="text" name="script" value="http://a.test.com/JS/src.js" style="display:none" />
<input type="submit" value="开始上传" />
</form>
<iframe name="upload" style="display:none"></iframe>
<script type="text/javascript">
document.domain="test.com";
</script>
后台:(www.b.test.com)
<?php
move_uploaded_file($_FILES['upload_file']['tmp_name'],'upload/' . $_FILES['upload_file']['name']);
$html = '<html><head>'
. '<script src="' . $_POST['script'] .'" type="text/javascript"></script>'
. '</head><body>'
. 'This data is from server!'
. '</body></html>';
echo $html;
?>
基本结构(完全跨域)
前端:(www.a.com)
<form action="http://www.b.com/io.php" method="POST" enctype="multipart/form-data" target="upload">
<input type="file" name="upload_file" />
<input type="text" name="tmpurl" value="http://www.a.com/tmp.html" style="display:none" />
<input type="submit" value="开始上传" />
</form>
<iframe name="upload" style="display:none"></iframe>
后台:(www.b.com)
<?php
move_uploaded_file($_FILES['upload_file']['tmp_name'],'upload/' . $_FILES['upload_file']['name']);
$data = 'This data is from server!'
header('Location:' . $_POST['tmpurl'] . '?data=' . $_data);
?>
cross-domain
By christyma
cross-domain
- 508