在 IE10 的 XHR 的麦子

IE10 的第四个平台简化了构建跨站点场景的跨浏览器一直工作,通过支持跨起源资源共享 (麦子)起始地址 (XHR)。简单、 灵活,XHR 的麦子使跨站点共享的数据。在最基本的情况下麦子使创建数据源,可以从任何站点,访问,并与几个小改动,您可以选择限制允许的网站,支持数据修改,并甚至允许身份验证。最重要的是麦子保持现有网站安全通过要求服务器参与。

简单跨起源 XHR

让我们看看如何跨起源 XHR 请求比较同一产地的请求。从脚本中,唯一的区别是传递到 open 方法的 URL。例如,我们正在读取的相册列表的脚本。

传统的 XHR

// Script running on http://photos.contoso.com

var xhr = new XMLHttpRequest();

xhr.onerror = _handleError;

xhr.onload = _handleLoad;

xhr.open("GET", "/albums", true);

xhr.send();

现在,我们想要访问的相册列表从另一来源。其他来源可以是完全不同的域或基本相同的域中具有不同的主机。无论怎样,只是指点在充分从另一个站点的 URL 就足以让浏览器自动发送麦子的请求。

麦子启用 XHR

// Script running on http://www.contoso.com

var xhr = new XMLHttpRequest();

xhr.onerror = _handleError;

xhr.onload = _handleLoad;

xhr.open("GET", "http://photos.contoso.com/albums", true);

xhr.send();

站点可以通过在特征检测中包装这为较旧的浏览器提供备用。检查"withCredentials"是最好的方法,因为它直接关系到 XHR 的麦子支持。

麦子启用 XHR 的特征检测

// Script running on http://www.contoso.com

var xhr = new XMLHttpRequest();

if ("withCredentials" in xhr) {

xhr.onerror = _handleError;

xhr.onload = _handleLoad;

xhr.open("GET", "http://photos.contoso.com/albums", true);

xhr.send();

} else {

// Fallback behavior for browsers without CORS for XHR

}

此时我们的客户端代码使得麦子请求直接以"http://photos.contoso.com",但是,请求将失败,返回任何数据。因为服务器不加入尚未出现故障。看看开发者工具快速给了我们一个错就错的想法。

Screenshot showing the F12 tools indicating no 'Access-Control-Allow-Origin' header was found.

在这里我们可以看到,服务器需要发送响应中的"Access-Control-Allow-Origin"标头。在我们的方案我们不开放我们任何网站访问,但是想启用访问单从"http://www.contoso.com"的专辑。此操作需要允许服务器以确定发出请求。检查我们传出的请求揭示了一个新的标头包含正是此信息,"Origin"。

简单的麦子请求标头

GET http://photos.contoso.com/albums HTTP/1.1

Origin: http://www.contoso.com

...

服务器使用此信息可以选择来限制访问网站的任何组。如果服务器始终添加"Access-Control-Allow-Origin"标头值为 '*' 然后所有网站将都有权访问。对于我们的方案,我们的服务器验证来源,然后设置"Access-Control-Allow-Origin"允许只"http://www.contoso.com"。

简单的麦子响应标头

HTTP/1.1 200 OK

Access-Control-Allow-Origin: http://www.contoso.com

...

在地方,上述更新,我们的"http://www.contoso.com"客户端现在可以从"http://photos.contoso.com"在服务器访问相册列表。

印前检查与跨起源 XHR

"简单"的麦子请求为止讨论是很好的基础,只读的情况下,如下载相册等。通过跨站点修改数据采取下一步需要在服务器上的更多工作。例如,我们在客户端创建新专辑中加入了代码。

var xhr = new XMLHttpRequest();

xhr.onerror = _handleError;

xhr.onload = _handleLoad;

xhr.open("PUT", "http://photos.contoso.com/albums", true);

xhr.send(JSON.stringify({ name: "New Album" }));

运行此作为-是不起作用。检查网络通信量,揭示了发送一个请求,但我们预期不会。

Screenshot of the F12 tools showing an OPTIONS preflight request.

什么浏览器实际发送被称为一个印前检查的请求。印前检查请求发送之前可能会导致服务器上的数据修改的请求。麦子规范中定义的非简单属性存在标识此类请求。这些属性范围从某些 HTTP 方法想"PUT"自定义 HTTP 标头。浏览器发送印前检查请求,请求服务器发送实际要求的权限。在我们的示例中,浏览器验证允许"PUT"的请求。

印前检查的请求

OPTIONS http://photos.contoso.com/albums HTTP/1.1

Origin: http://www.contoso.com

Access-Control-Request-Method: PUT

...

要获得实际的请求发送到浏览器需要一些服务器上的更改。再一次我们可以看看的开发工具的详细信息。

Screenshot showing the F12 tools indicating no 'Access-Control-Allow-Methods' list was found.

第一步是将认识到相同的 URL 有别于其他请求"OPTIONS"印前检查请求的服务器。通过确保"Access-Control-Request-Method"印前检查请求要求"PUT"从允许的起源,服务器将验证后,它将发送相应的批准通过"Access-Control-Allow-Methods"标头。

印前检查的响应

HTTP/1.1 200 OK

Access-Control-Allow-Origin: http://www.contoso.com

Access-Control-Allow-Methods: PUT

...

印前检查出是并批准后实际的请求将会发生。

实际的请求

PUT http://photos.contoso.com/albums HTTP/1.1

Origin: http://www.contoso.com

...

在这一点上,添加相册是技术上的完整,但我们的客户端代码不会知道,除非服务器的正确响应。专门的服务器仍必须在响应中包含"Access-Control-Allow-Origin"。

实际的响应

HTTP/1.1 200 OK

Access-Control-Allow-Origin: http://www.contoso.com

...

与客户端可以添加新专辑跨原点,并确认已成功完成该操作。

接下来的步骤

与其他新的平台功能配对麦子使有趣的情形。跨站点上传试驾跟踪跨起源文件上载使用麦子、 XHR、 FileAPI 和进度事件就是一例。

— — 托尼 · 罗斯,程序管理器、 Ie 浏览器

原文地址:https://www.cnblogs.com/shihao/p/2346361.html