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
 
 
 
参考资料:
 

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

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

    在开发中,经常会遇到多站点跨域访问后台服务获取数据的情况,解决方法有两种 自己写代理服务,访问代理服务,代理服务请求服务获取数据再返回: 设置浏览器可以跨域访问数据. 本文来讲如何设置IE浏览器跨域访 ...

  2. 允许浏览器跨域访问web服务端的解决方案

    今天和同事探讨了前后端如何真正实现隔离开发的问题,如果前端单独作为服务发布,势必会涉及到无法直接调用后端的接口的问题,因为浏览器是不允许跨域提交请求的. 所谓跨域访问,就是在浏览器窗口,和某个服务端通 ...

  3. php 允许浏览器跨域访问web服务端的解决方案

    今天和同事探讨了前后端如何真正实现隔离开发的问题,如果前端单独作为服务发布,势必会涉及到无法直接调用后端的接口的问题,因为浏览器是不允许跨域提交请求的. 所谓跨域访问,就是在浏览器窗口,和某个服务端通 ...

  4. [转] Chrome - 浏览器跨域访问设置(附:新老版本两种设置方法)

    [From] http://www.hangge.com/blog/cache/detail_1703.html 在进行前后分离的 webapp 开发,或者 H5 移动 App 开发时,我们会使用 P ...

  5. .NET中CORS跨域访问WebApi

    我这里只写基本用法以作记录,具体为什么看下面的文章: http://www.cnblogs.com/landeanfen/p/5177176.html http://www.cnblogs.com/m ...

  6. 配置nginx反向代理服务器,解决浏览器跨域调用接口的限制问题

    配置nginx反向代理服务器,解决浏览器跨域调用接口的限制问题 - 大venn的博客 - CSDN博客https://blog.csdn.net/u011135260/article/details/ ...

  7. 浏览器跨域请求之credentials

    -时间起源- 前段时间,需要弄个简单的网站出来,访问远程的api服务. 我是这么做的.首先是在搭建一个nodejs服务来运行前端页面.在我请求登录的时候,能成功返回相应的成功信息.然后,当我再次请求读 ...

  8. WebAPI的跨域访问CORS三种方法

    跨域访问: JSONP的原理利用<script>没有跨域访问的限制,利用<script>的src跨域访问api,api会根据数据把json包装在一个js里面,这样跨域的客户端拿 ...

  9. ASP.NET MVC & WebApi 中实现Cors来让Ajax可以跨域访问 (转载)

    什么是Cors? CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing).它允许浏览器向跨源服务器,发出XMLHttpReq ...

随机推荐

  1. ASP.NET Core 的启动和运行机制

    目录 ASP .NET Core 的运行机制 ASP .NET Core 的启动 ASP .NET Core 的管道和中间件 参考 ASP .NET Core 的运行机制 Web Server: AS ...

  2. jmap查看内存使用情况与生成heapdump--转

    http://www.webspherechina.net/home/space.php?uid=191&do=blog&id=7572 如果想分析自己的JAVA Applicatio ...

  3. 响应式下的雪碧图解决方案 - 活用background-size / background-position

    一.概述 在传统的居中布局时,我们常用background-position这个属性来进行雪碧图的定位,在减少数据量的同时,保证准确定位.在移动端使用越来越重的现在,以往的传统定位,已经无法达到目的, ...

  4. java 初始化顺序问题

    今天在<thinking in java>上面看了关于初始化问题,之前从来都没有深入考虑过,这次算是把它搞明白了,所以记录一下: 这个不是我看到的初始化顺序问题,在网上搜索的时候发现的,感 ...

  5. JS数组和函数 小记

    数组 JS中的数组来自window,是一个全局的对象,typeof的值是'object'. 创建数组: 1.Array(3):当只传一个值的时候,会生成一个长度为该数值的空数组. 2.Array(3, ...

  6. 微信小程序通过CODE换取session_key和openid

    微信小程序的用户信息获取需要请求微信的服务器,通过小程序提供的API在小程序端获取CODE,然后将CODE传入到我们自己的服务器,用我们的服务器来换取session_key和openid. 小程序端比 ...

  7. 面试遇到的mysql面试题

    1.MySQL数据库有哪些内置函数?1.数学函数 2.字符串函数 3.日期和时间函数 4.条件判断函数5.系统信息函数 6.加密和压缩函数 7.聚合函数8.格式或类型转化函数. 2.如何返回一张表的数 ...

  8. 分析解决 spring quartz 中出现的执行两次问题

    1. 问题描述 在开发询盘功能时,遇到一个需求,就是后台定时任务执行用电施工业务的工单下发. 使用的技术是 spring quartz,因为其他应用有先例,配置quartz 完成后,先写了一个 hel ...

  9. lambda 表达式学习笔记

    在Java中传递一个代码段并不容易,不能直接传递代码段.Java是一个面向对象语言,所以必须构造一个对象,这个对象的类需要一个方法能包含所需的代码.lambda的出现有效的解决这个问题,让代码变得更加 ...

  10. java 包装类和基础数据

    package com.tercher.demo; public class LangClass { public static void main(String[] args) { //所有的包装类 ...