浏览器跨域访问WebApi

webapi地址:wapapi.ebcbuy.com

web地址:wapweb.ebcbuy.com

在默认情况下这两个域名属于两个不同的域,他们之间的交互存在跨域的问题,但因为他们都同属于一个二级域名下,所以通过简单的设置就能实现跨域行为,但是考虑到实际生产环境中往往会出现两个域名

完全不同的情况,所以这里不考虑这种特殊的情况,使用更通用的方法来解决跨域的问题。

首先在webapi上有如下所示一个接口

我们需要在我们的web站点下通过ajax方式调用这个接口

此时我们可以看到如下的结果

通过分析上述的监视结果可以看到,这个ajax请求是成功的,但是因为响应头中没有告诉浏览器这个接口可以跨访问,浏览器就拒绝了将请求结果返回给用户。

通过在Action上进行断点,也可以看出,服务器已经收到请求并成功执行了

甚至浏览器本身也已经接收到了响应结果,因为跨域问题所以拒绝返回给用户

所以根据上述的错误提示,我们很容易就能解决跨域这个问题,就是需要在响应头中添加Access-Control-Allow-Origin这个响应数据。在IIS中我们可以在配置文件中直接配置这个响应头,让所有

的请求都能返回这个响应头,当然也可以使用代码对需要的接口进行单独返回相应的响应头,下面是web.config的配置

通过配置上述的配置,指定Access-Control-Allow-Origin响应头的值返回“*”,则表示任何域名都可以访问这个webapi

此时再次访问,可以看到访问成功,并输出了返回结果

在实际应用中,我们可能需要手动设置一些请求头发送给WebApi服务器,如下所示

此时再次访问webapi可以看到不一样的情况

从上图看到,这个请求不仅仅被终止了,而且不是以我们期望的post方式进行请求的,而是使用了options的方式。

了解http协议的同学可能会知道,options方法只是对服务器的一个探测,不会返回相应体。

这里就是浏览器对于跨域发送自定义请求头的一个限制,如果请求跨域并且手动设置了请求头,那么浏览器会发起两次请求,一次是Options的预检,询问服务器是否支持当前这个比较敏感的操作,如果服务器返回了期望的响应头数据,那么浏览器才会正在发起我们的请求。

通过上处分析,web网站要能事先跨站发送请求头,服务器必须支持options的预检,所以这里必须提供服务器的实现。

在微软的WebApi框架中我们可以使用Microsoft.AspNet.WebApi.Cors这个组件来提供支持。

使用Nuget进行安装

安装完毕后再WebApi上对其进行注册

注册完毕,最后我们只需要在我们需要跨域的Action使用特性就可以支持Options预检,进行跨域请求了

再次请求WebApi,我们可能发现请求并不是很成功,不过在IE浏览器下,调试工具给了我们很好的错误提醒。

从上图看到,在Options的预检的响应头中返回了两个Access-Control-Allow-Origin响应头,浏览器提示不允许这样的结果。

仔细回想一下上述的操作可以发现这个响应头其实是我们自己在webconfig中指派服务器自动发送了,这边的操作与之前的配置产生了冲突,删除刚才在Webconfig

中的配置节点即可

删除上述的节点后,再次请求服务器,可以发现正常返回结果了

在上述请求中,浏览器发起了一下Options预检与真正的Post请求。

有时候需要跨域向WebApi传递Cookie等信息,此时我们可能看到这里虽然成功向浏览器写入了Cookie,但是浏览器并不会主动发送Cookie到服务器

如果需要接收到Cookie信息,则需要设置SupportsCredentials属性为true

参考资料:

http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

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

时间: 2024-10-05 20:04:24

浏览器跨域访问WebApi的相关文章

设置IE浏览器跨域访问数据

在开发中,经常会遇到多站点跨域访问后台服务获取数据的情况,解决方法有两种 自己写代理服务,访问代理服务,代理服务请求服务获取数据再返回: 设置浏览器可以跨域访问数据. 本文来讲如何设置IE浏览器跨域访问数据,步骤如下: 打开[Internet选项],窗口如下 选择标签[安全],图片如下 选中[Internet],选择[自定义级别],图片如下:      如上图,在[其他]目录下,设置[跨域浏览窗口和框架]和[通过域访问数据源]为启用,确定,即设置成功! 如果站点为[本地intranet],则选择

浏览器跨域访问解决方案

浏览器跨域访问解决方案 2015年11月4日 18972次浏览 跨域的概念 跨域大家都知道,不同地址,不同端口,不同级别,不同协议都会构成跨域.例如:about.haorooms.com和www.haorooms.com都会构成跨域.总结起来只要协议.域名.端口有任何一个不同,都被当作是不同的域.下面举例,每两个一组. URL 说明 是否允许通信 http://www.haorooms.com/a.js http://www.haorooms.com/b.js 同一域名下 允许 http://w

解决浏览器跨域限制发送ajax请求

一.什么是浏览器跨域限制?本质是什么? 所谓浏览器跨域限制,其实是为了数据安全的考虑由Netscape提出来限制浏览器跨域访问数据的策略,这是一中约定,正式叫法为浏览器同源策略,目前已经在大多数浏览器中支持. 本质上,所谓浏览器同源策略即:不允许浏览器访问跨域的Cookie,ajax请求跨域接口等.也就是说,凡是访问与自己不在相同域的数据或接口时,浏览器都是不允许的. 最常见的例子:对于前后端完全分离的Web项目,前端页面通过rest接口访问数据时,会出现如下问题: 不允许发送POST请求:在发

浏览器跨域请求之credentials

-时间起源- 前段时间,需要弄个简单的网站出来,访问远程的api服务. 我是这么做的.首先是在搭建一个nodejs服务来运行前端页面.在我请求登录的时候,能成功返回相应的成功信息.然后,当我再次请求读取别的接口的时候,返回的信息确实提示我尚未登录.此时此刻,我一脸蒙逼.明明我已经登陆了啊.后来偶然得知这是因为浏览器的机制问题. -初步解决- 大概的意思是,默认情况下,标准的跨域请求是不会发送cookie等用户认证凭据的.所以,当你再次访问远程api的时候,cookie是不会被带上的,于是乎,服务

浏览器的跨域访问

一.浏览器介绍 对于Web应用来说,浏览器是最重要的客户端. 目前浏览器五花八门多得不得了,除了Chrome.IE.Firefox.Safari.Opera这些国外的浏览器外,百度.腾讯.360.淘宝.搜狗.傲游之类的,反正能做的都做了. 浏览器虽然这么多,但浏览器内核主要就以下4种: Trident:IE使用的内核. Gecko:Firefox使用的内核. WebKit:Safair和Chrome使用的内核.WebKit由苹果发明,Chrome也用了,但是Google又开发了V8引擎替换掉了W

Web安全技术(3)-浏览器的跨域访问

http://www.blogjava.net/linli/archive/2015/04/22/424584.html 一.浏览器介绍 对于Web应用来说,浏览器是最重要的客户端. 目前浏览器五花八门多得不得了,除了Chrome.IE.Firefox.Safari.Opera这些国外的浏览器外,百度.腾讯.360.淘宝.搜狗.傲游之类的,反正能做的都做了. 浏览器虽然这么多,但浏览器内核主要就以下4种: Trident:IE使用的内核. Gecko:Firefox使用的内核. WebKit:S

利用CORS配置实现jQuery对WebApi及MVC的跨域访问

js ajax操作中,默认不能进行跨域访问,我们可以通过CORS配置实现最简单的跨域访问.这种方式是在服务端进行跨域访问控制. 一.编写服务端代码 新建一个ASP.NET MVC/WebApi项目,在其中分别新建Api方法及MVC Action方法: WebApi方法如下: public class ValuesController : ApiController { // GET api/values public IEnumerable<string> Get() { return new

让浏览器进行跨域访问, 开发阶段需要跨域访问的测试方案 chrome的快捷方式里面 加 &quot;C:\Program Files (x86)\Google\Chrome\Application\chrome.exe&quot; --args --disable-web-security

Chrome浏览器 的快捷方式里加一个 命令可以使浏览器进行跨域访问 "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --args --disable-web-security     

PCB WebAPI跨域访问 实现方式

我们写WebAPI不仅自己系统调用,也需要给其它系统调用,那么如何实现跨域访问了,在这里介绍2种方法实现 方法一.修改Web.Config文件   实现 此方法是全局实现跨域,如果仅想某个方法实现跨域此方法不支持,可看下面一个方法自由程度更高些 <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add na