关于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 ...
随机推荐
- 基于AGS JS开发自定义贴图图层
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.前言 假设一个景区有多张图片需要在地图上展示,并且随着地图的缩放而缩 ...
- JavaEE开发基于Eclipse的环境搭建以及Maven Web App的创建
本篇博客就完整的来聊一下如何在Eclipse中创建的Maven Project.本篇博客是JavaEE开发的开篇,也是基础.本篇博客的内容干货还是比较多的,而且比较实用,并且都是采用目前最新版本的工具 ...
- C语言sqrt函数
引入头文件: # include <math.h> sqrt用来求给定值的平方根 double sqrt (double x) 在使用GCC编译时 加入 -lm参数
- 全新的 flow.ci Dashboard UI 上线
全新的 flow.ci Dashboard 页面上线了,更快捷地创建项目,构建列表页面新增分支,Pull Request 界面:侧边栏新增构建任务监控和项目监控,整个 Dashboard 界面焕然一新 ...
- HTML——超文本标记语言(表单及12个表单元素)
表单 格式: <form action=" " method="get/post" placehoder=" "></f ...
- javascript数组详解(js数组深度解析)【forEach(),every(),map(),filter(),reduce()】
Array 对象是一个复合类型,用于在单个的变量中存储多个值,每个值类型可以不同. 创建数组对象的方法: new Array(); new Array(size); new Array(element ...
- Spring + qyartz+多任务实现任务调度功能。
前记:如果配置多个任务不能触发的请仔细检查配置文件!!!!!! 不存在多个同时间任务不能触发的现象!!!! 这个东西记得不要设置成false.如果写了就是true.不写的话默认true. 下面开始贴配 ...
- post和get请求的区别
post和get请求的区别: 1.post发送的数据在请求体中,用户看不到 get发送的数据在地址栏中 2.post请求中有content-type,作用是告诉服务器,发送给服务器的数据格式,是和ur ...
- 【前端童鞋看过来!】给大家分享网盘里前端相关书籍,主要是和网络通信(HTTP/TCP/IP)及javascript相关的
百度云链接:https://pan.baidu.com/s/1kUPdf5H(无密码) 截图: <HTTP权威指南> [豆瓣书评]:此书第一部分是HTTP的概略,如果你没有时间,通读第一部 ...
- Struts2的类型转换(下)
Struts2提供的类型转换: Struts2提供的是一个名叫StrutsTypeConverter的抽象类,这个类实际上是DefaultTypeConverter的子类.当我们继承自该抽象类 时,要 ...