net core 跨域 jsonp ajax

参考文章https://www.cnblogs.com/yaopengfei/p/11191938.html

我用此文第三种方案:jsonp

1. 原始的jsonp模式

  在Asp.Net Core中支持,在.Net版本的webapi中是不支持,即在方法中声明一个接受参数与前端JSONP位置传递过来的进行对应,然后将数据进行包裹返回,$"{myCallBack}({xjs})"。以JQuery的Ajax请求为例,可以指定JSONP的名称,如下面代码指定为:myCallBack,如果省略,JSONP的名称则为:callback。

特别注意:凡是JSONP请求,GET请求地址的第一个参数则为JSONP位置配置的名称,如:http://localhost:29492/Home/GetInfor2?myCallBack=jQuery341001790888637311383_1564124488832&userName=ypf&_=1564124488833

服务器端代码:

net core 跨域 jsonp ajax
 1        /// <summary>
 2         /// 原始的JSONP模式,支持
 3         /// </summary>
 4         /// <param name="callBack"></param>
 5         /// <param name="userName"></param>
 6         /// <returns></returns>
 7         [HttpGet]
 8 
 9         public dynamic GetInfor1(string myCallBack, string userName)
10         {
11             var data = new
12             {
13                 id = userName + "001",
14                 userName = userName
15             };
16             string xjs = JsonConvert.SerializeObject(data);
17             return $"{myCallBack}({xjs})";
18         }
net core 跨域 jsonp ajax

前端代码:

net core 跨域 jsonp ajax
 1         $('#j_jsonp1').click(function () {
 2                 $.ajax({
 3                     url: 'http://localhost:29492/Home/GetInfor1',
 4                     type: "get",
 5                     dataType: "jsonp",
 6                     //需要和服务端回掉方法中的参数名相对应
 7                     //注释掉这句话默认传的名称叫callback
 8                     jsonp: "myCallBack",
 9                     cache: false,
10                     data: { userName: "ypf" },
11                     success: function (data) {
12                         console.log(data);
13                         alert(data.id + "," + data.userName);
14                     }
15                 });
16             });
net core 跨域 jsonp ajax

2. 利用过滤器判断请求来决定是否跨域

(1) 背景

  想实现服务器端方法正常写,该返回什么就返什么,如果是JSONP请求,则返回JSONP格式,如果是普通请求,则返回不同格式。

(2) 原理

  如果是jsonp请求的,如同下面这个地址:http://localhost:29492/Home/GetInfor2?myCallBack=jQuery341001790888637311383_1564124488832&userName=ypf&_=1564124488833, 第一个参数为myCallBack,如果有这个参数则证明是jsonp请求,需要拿到它的值;反之如果没有这个参数,则是普通请求,需要配置跨域策略了,才能拿到值。

  在过滤器中判断,如果是jsonp请求,则将数据进行包裹进行返回,如果是普通请求,则直接返回,然后把过滤器以特性[IsJsonpCallback]形式作用在GetInfor2方法上。

过滤器代码:

net core 跨域 jsonp ajax
 1  public class IsJsonpCallbackAttribute: ActionFilterAttribute
 2     {
 3         private const string CallbackQueryParameter = "myCallBack";
 4         public override void OnActionExecuted(ActionExecutedContext context)
 5         {
 6 
 7             string text = context.HttpContext.Request.QueryString.Value;
 8             string[] arrys = text.Split('&');
 9             if (arrys[0].Contains(CallbackQueryParameter))
10             {
11                 var myCallBackValue = arrys[0].Split('=')[1];
12                 var result = $"{myCallBackValue}({((ObjectResult)context.Result).Value})";
13                 context.HttpContext.Response.WriteAsync(result);
14             }
15 
16             base.OnActionExecuted(context);
17         }
18     }
net core 跨域 jsonp ajax

服务器端代码:

net core 跨域 jsonp ajax
 1      /// <summary>
 2         /// 改造后的Jsonp(请求是Jsonp格式,则返回jsonp格式,反之普通格式)
 3         /// </summary>
 4         /// <param name="callBack"></param>
 5         /// <param name="userName"></param>
 6         /// <returns></returns>
 7         [HttpGet]
 8         [IsJsonpCallback]
 9 
10         public dynamic GetInfor2(string userName)
11         {
12             var data = new
13             {
14                 id = userName + "001",
15                 userName = userName
16             };
17             string xjs = JsonConvert.SerializeObject(data);
18             return $"{xjs}";
19         }
net core 跨域 jsonp ajax

前端代码:

net core 跨域 jsonp ajax
 1   //2. 利用过滤器改造-jsonp请求
 2             $('#j_jsonp2').click(function () {
 3                 $.ajax({
 4                     url: 'http://localhost:29492/Home/GetInfor2',
 5                     type: "get",
 6                     dataType: "jsonp",
 7                     //需要和服务端回掉方法中的参数名相对应
 8                     //注释掉这句话默认传的名称叫callback
 9                     jsonp: "myCallBack",
10                     cache: false,
11                     data: { userName: "ypf" },
12                     success: function (data) {
13                         console.log(data);
14                         alert(data.id + "," + data.userName);
15                     }
16                 });
17             });
18             //3. 利用过滤器改造-普通请求
19             $('#j_jsonp21').click(function () {
20                 $.ajax({
21                     url: 'http://localhost:29492/Home/GetInfor2',
22                     type: "get",
23                     dataType: "json",
24                     cache: false,
25                     data: { userName: "ypf" },
26                     success: function (data) {
27                         console.log(data);
28                         alert(data.id + "," + data.userName);
29                     }
30                 });
31             });
net core 跨域 jsonp ajax

3. 利用程序集【WebApiContrib.Core.Formatter.Jsonp】改造

  GitHub地址:https://github.com/WebApiContrib/WebAPIContrib.Core/tree/master/src/WebApiContrib.Core.Formatter.Jsonp

  通过Nuget引入上面程序集,在ConfigureServices中的AddMvc中,书写代码 option => option.AddJsonpOutputFormatter(),即可实现JSONP请求返回JSONP格式,普通请求返回不同格式, 默认情况下回调参数为“callback”,也可以手动配置:option =>option.AddJsonpOutputFormatter(mvcOption.OutputFormatters.OfType<JsonOutputFormatter>().FirstOrDefault(), "myCallBack")

默认回调参数配置的代码:

1   services.AddMvc(    
2        //不写参数的话,走的是默认回调参数 callback
3        option => option.AddJsonpOutputFormatter()
4   ).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

命名回调参数配置的代码:

1  MvcOptions mvcOption = new MvcOptions();
2  services.AddMvc(    
3     //配置JSONP的方案二,回调参数配置为myCallBack
4     option =>option.AddJsonpOutputFormatter(mvcOption.OutputFormatters.OfType<JsonOutputFormatter>().FirstOrDefault(), "myCallBack")
6   ).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

通过上面的代码配置,即可实现JSONP请求返回JSONP格式,普通请求返回不同格式。(原理去github上看代码)

上一篇:使用JSONP实现跨域


下一篇:C#知识点提炼期末复习专用