视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001 知道1 知道21 知道41 知道61 知道81 知道101 知道121 知道141 知道161 知道181 知道201 知道221 知道241 知道261 知道281
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
ASP.Net WebAPI与Ajax进行跨域数据交互时Cookies数据的传递
2020-11-27 22:35:46 责编:小采
文档

前言

最近公司项目进行架构调整,由原来的三层架构改进升级到微服务架构(准确的说是服务化,还没完全做到微的程度,颗粒度没那么细),遵循RESTFull规范,使前后端完全分离,实现大前端思想。由于是初次尝试,中途也遇到了不少问题。今天就来讨论一下其中之一的问题,WebAPI与前端Ajax 进行跨域数据交互时,由于都在不同的二级域名下(一级域名相同),导致Cookies数据无法获取。

最开始通过头部(Header)将Cookies传输到其WebAPI,也能解决问题。

下面讲述另外一种解决方案。

解决过程:

步骤一:将Cookies的Domain(域)设置成一级域名,例如:“.wbl.com”(a.wbl.com域名下)

这是前提,此时在其中一个WebAPI中设置了Cookies后,用浏览器直接访问其它的WebAPI是可以获取到Cookies的。例如:a.wbl.com域名下设置的Cookies,用浏览器直接访问b.wbl.com域名的WebAPI是可以获取到Cookies的。但是用c.web.com域名下的Ajax访问b.wbl.com时,就无法获取到Cookies了,这是由于浏览器中Ajax的权限相对较低,Ajax无法跨域问题导致。

写入Cookies代码:

/// <summary>
 /// 给指定的 Cookies 赋值
 /// </summary>
 /// <param name="cookKey">Cookies 名称</param>
 /// <param name="value">Cookies 值</param>
 /// <param name="domain">设置与此 Cookies 关联的域(如:“.tpy100.com”)(可以使该域名下的二级域名访问)</param>
 public static void SetCookiesValue(string cookKey, string value, string domain)
 {
 HttpCookie cookie = new HttpCookie(cookKey);
 cookie.Value = value;
 cookie.HttpOnly = true;
 if (!string.IsNullOrEmpty(domain) && domain.Length > 0)
 cookie.Domain = domain;
 HttpContext.Current.Response.Cookies.Add(cookie);
 }

步骤二:JQuery中Ajax使用Jsonp数据类型解决跨域问题(c.wbl.com域名下)

前后端需要定义统一的回调(Callback)函数名。

前端Ajax代码:

// 设置Cookies
 function set() {
 var url = "http://a.wbl.com/api/setvalue/888888";
 $.ajax({
 type: "get",
 url: url,
 dataType: "jsonp",
 jsonp: "callbackparam", //服务端用于接收callback调用的function名的参数
 jsonpCallback: "success_jsonpCallback", //callback的function名称
 success: function (json) {
 console.log(json);
 alert(json);
 },
 error: function () {
 alert('fail');
 }
 });
 }
 // 获取Cookies
 function get() {
 var url = "http://b.wbl.com/api/getvalue";
 $.ajax({
 type: "get",
 url: url,
 dataType: "jsonp",
 jsonp: "callbackparam", //服务端用于接收callback调用的function名的参数
 jsonpCallback: "success_jsonpCallback", //callback的function名称
 success: function (json) {
 console.log(json);
 alert(json);
 },
 error: function () {
 alert('fail');
 }
 });
 }

步骤三:WebAPI中返回jsonp数据类型

Jsonp格式:

success_jsonpCallback({“Cookies”:”888888”})

由于这种格式与json格式有所不同,只用WebAPI里的返回IHttpActionResult或HttpRequestMessage类型不行,最后通过流的方式输出才实现了这个格式。

WebAPI代码:

[Route("api/GetValue")]
 [HttpGet]
 public void GetValue()
 {
 string ccc = MyTools.Request.GetString("callbackparam");
 var a = new { name = "Cookies", value = MyTools.Cookies.GetCookiesValue("name") };
 string result = ccc + "({\"Cookies\":\"" + MyTools.Cookies.GetCookiesValue("name") + "\"})";
 //var response = Request.CreateResponse(HttpStatusCode.OK);
 //response.Content = new StringContent(result, Encoding.UTF8);

 HttpContext.Current.Response.Write(result);
 HttpContext.Current.Response.End();
 // return response;
 }
 [Route("api/SetValue/{id}")]
 [HttpGet]
 public void SetValue(int id)
 {
 //string domain = "";
 string domain = ".wbl.com";
 MyTools.Cookies.ClearCookies("name", domain);
 MyTools.Cookies.SetCookiesValue("name", id.ToString(), domain);

 string ccc = MyTools.Request.GetString("callbackparam");
 string result = ccc + "({\"result\":\"设置成功\"})";

 HttpContext.Current.Response.Write(result);
 HttpContext.Current.Response.End();
 }

最终效果:

后言:

这只是解决这个问题的一种方法。百度后还有一种通过第三方插件(Cross-Origin、Help Page)来处理的,后续在进行实验。各位路过的大神如有更好的方法,望不要吝啬,请赐教!菜鸟感激不尽!

下载本文
显示全文
专题