关于WebService、WebApi的跨域问题
随着移动互联网的发展, 传统营销模式往网站以及移动客户端转移已经成为一种趋势。接触过互联网开发的开发者肯定会很熟悉两种网络服务WebApi、WebService。在使用JavaScript进行数据交互时会遇到一个问题,那就是JavaScript的同源策略,简单的来讲同源策略就是指一段脚本只能读取来自同一来源的窗口和文档的属性,这里的同一来源指的是主机名、协议和端口号的组合。以下是我对同源策略的理解,可能不完善:
请求URL | 请求结果 | 原因 |
http://wangyu.testurl.com/WebApi/test | YES | 当前域 |
http://wangyu.testurl.com/WebApi/test2 | YES | 当前域 |
http://wangyu.testurl.com/WebApi2/test | NO | 跨域/端口不同 |
http://wangyu2.testurl.com/WebApi2/test | NO | 跨域/主机不同 |
https://wangyu.testurl.com/WebApi/test | NO | 协议不同 |
一、WebApi的跨域问题解决:
1.从客户端来解决跨域问题:
从客户端来解决跨域问题就是从调用方的解决跨域访问,需要每个客户端自己来做处理,常见的JSONP回调方式。(本文略过,本博文主要讲解从服务端解决跨域的方法)
2.从服务端来解决跨域:
(1)ASP.NET Web API对CORS提供的原生支持的实现:
ASP.NET Web API对CORS提供的原生支持实现在一个名为“Microsoft ASP.NET Web API 2 Cross-Origin Support”的NuGet包中。当我们安装这个包之后,现 有的packages目录下会添加两个名称分别为“Microsoft.AspNet.Cors”和“Microsoft.AspNet.WebApi.Cors”,针对保存其中的两个程序集(System.Web.Cors.dll和System.Web.Http.Cors.dll)的引用被自动添加到项目中。
具体操作步骤:①VS工具条“工具”->"NuGet工具管理器"->"程序包管理控制台"②在控制台输入Install-Package Microsoft.AspNet.WebApi.Cors(当然要在联网状态)此时编译器就会为我们安装对应的程序集。在安装程序集之后,跨域支持是默认关闭的,需要我们添加部分代码:
- public static class WebApiConfig
- {
- public static void Register(HttpConfiguration config)
- {
- //打开跨域支持
- config.EnableCors();
- // Web API 配置和服务
- // 将 Web API 配置为仅使用不记名令牌身份验证。
- config.SuppressDefaultHostAuthentication();
- config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
- // Web API 路由
- config.MapHttpAttributeRoutes();
- config.Routes.MapHttpRoute(
- name: "DefaultApi",
- routeTemplate: "api/{controller}/{id}",
- defaults: new { id = RouteParameter.Optional }
- );
- }
- }
然后在对应的控制器添加对应的属性,就可以让特定的控制器支持跨域访问。比如我自己的示例:
- namespace Jiuka.Webapi.Controllers
- {
- /// <summary>
- /// Class UserController.
- /// </summary>
- [EnableCors(origins: "*", headers: "*", methods: "*")]
- public class UserController : ApiController
- {
- /// <summary>
- /// 注册用户
- /// </summary>
- /// <param name="model">The model.</param>
- /// <returns>System.String.</returns>
- [System.Web.Http.HttpPost]
- public string NewUser([FromBody] MUserInfo model)
- {
- bool res = WcfCallHelper.Instance.Invoke<bool, IUserService, MUserInfo>(model, "RegisteUser");
if(!res)
{
return "注册失败!";
}- MOperateLog temp = new MOperateLog();
- temp.KeyID = model.KeyID;
- temp.Operate = "注册";
- temp.OpUser = model.Name;
- temp.TrackID = model.KeyID;
- temp.Detail = string.Format("{0}注册了账号,初始密码是:{1}", model.Name, model.Password);
- LogMannager.WriteLog(temp);
- return "注册成功!";
- }
- }
- }
[EnableCors(origins: "*", headers: "*", methods: "*")]里面*号表示不加任何限定,具体的使用方法可以自己去学习。提示:当我们自定义参数类型时,要为参数加上[FromBody]属性,并且在Ajax提交的时候,不加DataType选项,要不然会出问题,亲测过!
3.从部署的服务器的配置上解决跨域限制问题:
当我们的WebApi需要跨域调用调试或者是完成了本地调试不要上服务器开始外网服务时,需要将我们写好的web服务部署在服务器上,这时候可以通过服务器上的一些配置选项来解决跨域限制问题。
具体操作方法:当我们把我们的服务部署到服务器之后打开IIS管理器,选中对应的服务,我们会看到如下一个菜单选项:
选则HTTP响应标头菜单,添加如下三个响应标头:
Access-Control-Allow-Origin 表示请求的来源,其格式:”地址:端口号”,”域名”,当其值为”*”表示不限定。标头设置好之后重新启动网站,跨域访问限制问题就解决了。
二、WebService的跨域问题解决:
1.从客户端调用来解决跨域限制:同上的,采用JSONP方式调用(掠过)。
2.从服务端解决跨域限制:①采用WebApi的同样的方法,设置我们的IIS服务器HTTP响应标头②采用ServiceStack服务框架
采用ServiceStack服务框架跨域的具体实现:
首先在编译器上安装好ServiceStack服务框架模板,建立新的工程之后,整个项目的目录如图(Yibaobao.BasicComponents是我自己定义的基础组件程序集,并不是框架提供):
按照ServiceStack服务框架建立好一个项目之后,我们就可以根据我们的实际需求来定义我们的服务接口以及相应的数据模型,ServiceStack的具体实现这里就不做赘述,在这里我们就讲解跨域的解决部分,在Service层目录里面有一个“AppHost.cs”文件,在这里面我们可以对我们的WebService做一些设置,比如我们的跨域支持也是在这里完成,改写“AppHost.cs”文件的代码如下:
- using Funq;
- using ServiceStack;
- using Yibaobao.WebService.ServiceInterface;
- using System.ServiceModel;
- namespace Yibaobao.WebService
- {
- public class AppHost : AppHostBase
- {
- /// <summary>
- /// Default constructor.
- /// Base constructor requires a name and assembly to locate web service classes.
- /// </summary>
- public AppHost()
- : base("Yibaobao.WebService", typeof(MyServices).Assembly)
- {
- }
- /// <summary>
- /// Application specific configuration
- /// This method should initialize any IoC resources utilized by your web service classes.
- /// </summary>
- /// <param name="container"></param>
- public override void Configure(Container container)
- {
- base.SetConfig(new HostConfig
- {
- GlobalResponseHeaders = {
- { "Access-Control-Allow-Origin", "*" },
- { "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" },
- { "Access-Control-Allow-Headers", "Content-Type" },
- },
- });
- }
- }
- }
在重写的Config函数里面也是加了一个响应标头,和配置IIS服务器感觉类似,只是这是在代码中直接解决。
如有什么问题或是错误,请大家多多指正。
关于WebService、WebApi的跨域问题的更多相关文章
- asp.net core webapi之跨域(Cors)访问
这里说的跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被当作 ...
- 简析ASP.NET WebApi的跨域签名
之前的文章写了关于WebApi的跨域问题,当中的方法只是解决了简单请求的跨域问题而非简单请求的跨域问题则没有解决. 要弄清楚 CORS规范将哪些类型的跨域资源请求划分为简单请求的范畴,需要额外了解几个 ...
- .NET压缩图片保存 .NET CORE WebApi Post跨域提交 C# Debug和release判断用法 tofixed方法 四舍五入 (function($){})(jQuery); 使用VUE+iView+.Net Core上传图片
.NET压缩图片保存 需求: 需要将用户后买的图片批量下载打包压缩,并且分不同的文件夹(因:购买了多个用户的图片情况) 文章中用到了一个第三方的类库,Nuget下载 SharpZipLib 目前用 ...
- webapi支持跨域访问
写在前面 在实际应用中,跨域请求还是比较常见的,如何上接口直接支持跨域的访问呢? demo 场景项目A有个接口用来获取用户列表,现在项目b也有个功能需要加载用户列表.这两个项目在两个域名下,至少端口好 ...
- webapi+ajax跨域问题及cookie设置
最近小玩了点东西,发现简单的东西总能遇到点问题 1.webapi跨域设置 [EnableCors(origins: "*", headers: "*", met ...
- .net core webapi+vue 跨域访问
最近在做一个前后端分离的示例,以下代码完美解决跨域的问题 一.后端服务 1.首先我们建一个.net core webapi的项目 2.项目引用Microsoft.AspNetCore.Cors 包 3 ...
- WebAPI的跨域访问CORS三种方法
跨域访问: JSONP的原理利用<script>没有跨域访问的限制,利用<script>的src跨域访问api,api会根据数据把json包装在一个js里面,这样跨域的客户端拿 ...
- 后端调用接口在通过webService发布 解决跨域问题
1.新建一个空的项目 2.添加一个WebService新项 asmx格式的 3.在这里面写方法 加上[WebMethod]标识 前端就可以调用 4.发布WebService 右键服务 添加服 ...
- C# WebAPI设置跨域
设置前端跨域请求很简单,只需要两个步骤 1.安装package Install-Package Microsoft.AspNet.WebApi.Cors 2.WebApiConfig类中,Regist ...
随机推荐
- ps-色彩饱和度的设计
1- 图层区—复制背景图层 防止原图修改失败后无法还原 2- 选项区——选择—色彩范围 以色彩为标准来对图片进行选区 3- 点击图片上 ...
- 20155304 2016-2017-2 《Java程序设计》第四周学习总结
20155304 2016-2017-2 <Java程序设计>第四周学习总结 教材学习内容总结 第六章 继承: 概念: 面向对象中,为避免多个类间重复定义共同行为.(简单说就是将相同的程序 ...
- 【iOS】7.4 定位服务->2.1.3.2 定位 - 官方框架CoreLocation 功能2:地理编码和反地理编码
本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. 本文相关目录: ================== 所属文集:[iOS]07 设备工具 === ...
- 完全关闭IIS日志,包括System32下的LogFile
早上突然发现网站访问不了了,登陆服务器一看,是C盘满了. 查一看,是IIS产生了70多G的日志,但明明已关闭日志了,还是会产生. 产生的目录在:C:\Windows\System32\LogFiles ...
- PyQt QListWidget修改列表项item的行高
百度,谷歌之后都说用setHintSize(self,QCore.QSize(width,height)),然并卵,后来用qss修改就可以了,具体用法如下 # emaillist是我给QListWid ...
- pyqt4实现tab界面切换
(转:https://segmentfault.com/q/1010000005143428)
- iwebshop中的增删改查
<?php class Text extends IController { public function hello() { $this->redirect('hello'); } p ...
- div的优缺点
div+css优缺点 产生背景 HTML语言自HTML4.01以来,不再发布新版本,原因就在于HTML语言正变得越来越复杂化.专用化.即标记越来越多,甚至各个浏览器生产商也开发出只适合于其特定浏览 ...
- RN 导入原有Xcode项目中,引入Pod依赖出现的问题与解决
RN 导入原有Xcode项目中,引入Pod依赖出现的问题与解决 前言 最近学习React Native技术.将RN引入到原来Xcode项目中有一步:给原来Xcode项目添加所需要的Pod依赖 写好Po ...
- 【转】air调用windows自带的虚拟键盘
原文:http://bbs.9ria.com/blog-73243-19560.html 最近在做一个东西,需要用到虚拟键盘.刚开始准备用as3开发一套,结果突然想起来windows有个自带的虚拟键盘 ...