关于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 ...
随机推荐
- struct 和typedef struct的区别
和int char一样struct也是一种数据类型,也可以声明变量--结构变量. 定义结构体变量的一般格式为: struct 结构名 { 类型 变量名; 类型 变量名; ... }结构变量; 另一种常 ...
- Https握手协议以及证书认证
1. 什么是https Https = http + 加密 + 认证 https是对http的安全强化,在http的基础上引入了加密和认证过程.通过加密和认证构建一条安全的传输通道.所以https可以 ...
- App对接支付宝移动支付功能
前段时间看了下app对接支付宝移动支付的功能,并自己总结了下支付宝移动支付的实现流程 一.申请流程 前提是已有现成的应用. 1. 申请地址 https://b ...
- 搭建高可用mongo集群3.4版本
搭建高可用mongo集群3.4版本 说在开始之前:在搭建这个环境之前,已经有了一个师兄搭好的环境,虽然一样很棒,但是没有经过自己的手出来的东西,还是不属于自己,所以摸索着自己搭建一个吧,好巧不巧的是, ...
- linux上执行 xhost unable to open display
linux下执行xhost命令报错:unable to open display,解决方法,linux 下通过xhost进入图形界面,经常会出现报错"unable to open disp ...
- “倔驴”一个h5小游戏的实现和思考(码易直播)——总结与整理
3月23日晚上8点半(中国队火拼韩国的时候),做了一期直播分享.15年做的一个小游戏,把核心代码拿出来,现场讲写了一遍,结果后面翻车了,写错了两个地方,导致运行效果有点问题,直播边说话边写代码还真不一 ...
- node.js报错throw err; // Rethrow non-MySQL errors e:\serverTest\node_modules\mysql\lib\protocol\Parser.js:79 解决方法
今天在用node+angular做后台时,需要使用session保存登陆状态的时候,遇到了此问题,问题直译为非mysql问题,我也在后台取到的登陆用户名和密码,确实不是数据库问题.最后发现在使用ses ...
- iOS开发之JSON & XML
1.概述 JSON (1) 作为一种轻量级的数据交换格式,正在逐步取代XML,成为网络数据的通用格式 (2) 基于JavaScript的一个子集 (3) 易读性略差,编码手写难度大,数据量小 (4) ...
- Python全栈开发第13天
#多用户登录 import getpass #引用getpass import os #引用os import configparser #引用配置文件操作的库 count = 0 count_oth ...
- [python爬虫]爬取学校教务处成绩
学校教务处网站 登陆窗口 表单数据 观察登陆窗口和提交的表单数据可知只要将账号.密码.验证码正确赋值提交即可模拟登陆. 账号和密码都有,问题的关键就在验证码上. 右键验证码图片审查观察源码如下图: 刚 ...