跨域

目前控制台的解决办法

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);

?>
Made with Slides.com