----------------------------------------------------------------------------------------------------------

http://www.ruanyifeng.com/blog/2016/04/cors.html

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。

浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

二、两种请求

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

只要同时满足以下两大条件,就属于简单请求。

(1) 请求方法是以下三种方法之一:

  • HEAD
  • GET
  • POST

(2)HTTP的头信息不超出以下几种字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

凡是不同时满足上面两个条件,就属于非简单请求。

浏览器对这两种请求的处理,是不一样的。

三、简单请求

3.1 基本流程

对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。

下面是一个例子,浏览器发现这次跨源AJAX请求是简单请求,就自动在头信息之中,添加一个Origin字段。


GET /cors HTTP/1.1
Origin: http://api.bob.com
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

上面的头信息中,Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。

如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段(详见下文),就知道出错了,从而抛出一个错误,被XMLHttpRequestonerror回调函数捕获。注意,这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。

如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段。


Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8

上面的头信息之中,有三个与CORS请求相关的字段,都以Access-Control-开头。

(1)Access-Control-Allow-Origin

该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。

(2)Access-Control-Allow-Credentials

该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。

(3)Access-Control-Expose-Headers

该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader('FooBar')可以返回FooBar字段的值。

3.2 withCredentials 属性

上面说到,CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段。


Access-Control-Allow-Credentials: true

另一方面,开发者必须在AJAX请求中打开withCredentials属性。


var xhr = new XMLHttpRequest(); xhr.withCredentials = true;

否则,即使服务器同意发送Cookie,浏览器也不会发送。或者,服务器要求设置Cookie,浏览器也不会处理。

但是,如果省略withCredentials设置,有的浏览器还是会一起发送Cookie。这时,可以显式关闭withCredentials


xhr.withCredentials = false;

需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。

JS设置document.domain实现跨域

document.domain

用来得到当前网页的域名。
比如在地址栏里输入:

代码如下:
javascript:alert(document.domain); //www.jb51.net

我们也可以给document.domain属性赋值,不过是有限制的,你只能赋成当前的域名或者基础域名。
比如:

代码如下:
javascript:alert(document.domain = "jb51.net"); //jb51.net
javascript:alert(document.domain = "www.jb51.net"); //www.jb51.net

上面的赋值都是成功的,因为www.jb51.net是当前的域名,而jb51.net是基础域名。
但是下面的赋值就会出来"参数无效"的错误:

代码如下:
javascript:alert(document.domain = "cctv.net"); //参数无效
javascript:alert(document.domain = "www.jb51.net"); //参数无效

因为cctv.net与www.jb51.net不是当前的域名也不是当前域名的基础域名,所以会有错误出现。这是为了防止有人恶意修改document.domain来实现跨域偷取数据。

利用document.domain 实现跨域:
前提条件:这两个域名必须属于同一个基础域名!而且所用的协议,端口都要一致,否则无法利用document.domain进行跨域.
Javascript出于对安全性的考虑,而禁止两个或者多个不同域的页面进行互相操作。
相同域的页面在相互操作的时候不会有任何问题。

比如在:aaa.com的一个网页(a.html)里面 利用iframe引入了一个bbb.com里的一个网页(b.html)。
这时在a.html里面可以看到b.html里的内容,但是却不能利用javascript来操作它。因为这两个页面属于不同的域,在操作之前,js会检测两个页面的域是否相等,如果相等,就允许其操作,如果不相等,就会拒绝操作。
这里不可能把a.html与b.html利用JS改成同一个域的。因为它们的基础域名不相等。(强制用JS将它们改成相等的域的话会报跟上面一样的"参数无效错误。")

所以如果在a.html里引入aaa.com里的另一个网页,是不会有这个问题的,因为域相等。
有另一种情况,两个子域名:
aaa.xxx.com
bbb.xxx.com
aaa里的一个网页(a.html)引入了bbb 里的一个网页(b.html),
这时a.html里同样是不能操作b.html里面的内容的。
因为document.domain不一样,一个是aaa.xxx.com,另一个是bbb.xxx.com。
这时我们就可以通过Javascript,将两个页面的domain改成一样的,
需要在a.html里与b.html里都加入:

代码如下:
document.domain = "xxx.com";

这样这两个页面就可以互相操作了。也就是实现了同一基础域名之间的"跨域"

转载于:https://www.cnblogs.com/qdcnbj/p/8440713.html

跨域资源请求(除jsonp以外)的方法相关推荐

  1. Cors跨域资源请求详解

    介绍 Cors全称为"跨域资源共享"(Cross-origin resource sharing),是一个W3C标准,一种浏览器机制,可实现对位于应用程序域之外的资源的受控访问,对 ...

  2. Nuxt如何发起跨域资源请求?

    用于 Nuxt.js 的 http-proxy 中间件解决方案 npm i @nuxtjs/proxy -D 在 nuxt.config.js 配置文件中添加对应的模块,并设置代理 modules: ...

  3. php csrf jsonp,读取型CSRF(JSONP劫持、CORS跨域资源读取、Flash跨域劫持)

    我们只熟悉写入型csrf,像修改用户信息--今天介绍一下读取型CSRF,使用DoraBox这个靶场来演示一波! 地址:https://github.com/Acmesec/DoraBox JSONP劫 ...

  4. 跨域post请求实现方案小结--转

    [名词解释] 跨域:https://developer.mozilla.org/en-US/docs/JavaScript/Same_origin_policy_for_JavaScript 同源策略 ...

  5. 跨域(CORS)请求问题[No 'Access-Control-Allow-Origin' header is present on the requested resource]常见解决方案

    基本概念 跨域(CORS)请求:同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略, ...

  6. apache字体文件跨域_apache如何解决跨域资源访问

    很多时候,大中型网站为了静态资源分布式部署,加快访问速度,减轻主站压力,会把静态资源(例如字体文件.图片等)放在独立服务器或者CDN上,并且使用独立的资源域名(例如res.test.com) 但是在实 ...

  7. 来吧学学.Net Core之登录认证与跨域资源使用

    序言 学习core登录认证与跨域资源共享是越不过的砍,所以我在学习中同样也遇到啦这两个问题,今天我们就用示例来演示下使用下这2个技术点吧. 本篇主要内容如下: 1.展示一个登录认证的简单示例 2.跨域 ...

  8. 跨域 cors 请求两次_请求两次的故事-CORS

    跨域 cors 请求两次 The story of requesting twice, allow me to explain how it all began. 请求两次的故事,让我解释一下这是如何 ...

  9. AJAX 跨域调用和 Java 跨域 发送请求

    AJAX 跨域调用 前台代码: Html代码   <script type="text/javascript" src="jquery-1.7.2.min.js&q ...

最新文章

  1. 用SQL命令查看Mysql数据库大小
  2. 【译】MVVM Tutorial with ReactiveCocoa: Part 1/2
  3. java清空字符串_java面向对象,垃圾回收机制
  4. 获取前台HTML控件的值(select)
  5. halcon python_使用pythonnet调用halcon脚本
  6. 5张图搞懂Java深浅拷贝
  7. 【已解决】nimfa 环境的详细搭建过程 + 各种依赖库的安装、下载、调试
  8. 如何使用Kubernetes的configmap通过环境变量注入到pod里
  9. bow 折叠键盘 linux,bow便携折叠蓝牙键盘体验
  10. poj 2029 Get Many Persimmon Trees 二维树状数组
  11. 【HANA系列】SAP HANA中null变成问号的问题
  12. python查找文字在图片中的位置_python实现简单图片文字识别翻译OCR
  13. axure通用元件库 Pc、Web端原型图组件库高保真UI rp源文件
  14. html2canvas给图片添加水印,canvas 为图片添加水印
  15. 网线百兆与千兆的接法
  16. 做一个企业网站需要多少钱?
  17. VMware与宿主机实现共享文件
  18. 【装机必备】电脑优化清理工具
  19. 德国的共享杯,共享碗--还有什么不能共享?
  20. VPS云主机套餐中都包含什么

热门文章

  1. Linux入门之VIM快捷使用
  2. spark共享变量(广播变量Broadcast Variable,累加器Accumulators)
  3. ZH奶酪:PHP遍历目录/文件的3种方法
  4. Oracle 数据文件(Datafile ) 大小 限制 说明
  5. 黄聪:C#设置Word中表格某个列宽
  6. c++语言 xml数据绑定技术简介
  7. SQLite指南(1) -- SQLite的特性
  8. 蓝桥杯 ALGO-78 算法训练 确定元音字母位置
  9. 蓝桥杯 ADV-194算法提高 盾神与积木游戏(贪心)
  10. 京沪无人驾驶复兴号高铁_河北高铁走到今天这一步,太不容易了...