net core 跨域 jsonp ajax
参考文章https://www.cnblogs.com/yaopengfei/p/11191938.html
自己写的例子:
后端:
[HttpGet("BatchAdd")]
[IsJsonpCallback]
public dynamic BatchAdd(string myCallBack, string param)
{
BiYouXuePermissionAddParam model = JsonConvert.DeserializeObject<BiYouXuePermissionAddParam>(param);
var result = JsonConvert.SerializeObject(_biYouXuePermissionService.BatchAdd(model).Result);
return $"{result}";
}
public class IsJsonpCallbackAttribute : ActionFilterAttribute
{
private const string CallbackQueryParameter = "CallBack";
public override void OnActionExecuted(ActionExecutedContext context)
{
string text = context.HttpContext.Request.QueryString.Value;
string[] arrys = text.Split('&');
if (arrys[0].Contains(CallbackQueryParameter))
{
var myCallBackValue = arrys[0].Split('=')[1];
var result = $"{myCallBackValue}({((ObjectResult)context.Result).Value})";
context.HttpContext.Response.WriteAsync(result);
}
base.OnActionExecuted(context);
}
}
前端:
var datas = { "TeacherIds": "" + teacherids + "", "PermissionLevel": "" + t_level+"", "StudentGrade": 2, "StudentYear": t_studentYear, "AcademicYear": t_academicYear, "CourseID": t_course, "SubjectType": t_subjectType } var geturl = $.trim($('#WebApiUrl').val()) + "TeacherPermisiion/BatchAdd"; $.ajax({ type: "get", url: geturl, contentType: "application/json; charset=utf-8", dataType: "jsonp", cache: false, data: { param: JSON.stringify(datas) }, //async: true, jsonp: "myCallBack", success: function (d) { debugger if (d.success == true) { layer.alert('权限添加成功!'); } else { layer.alert(d.mag); } $('#myachievementbody').hideLoading(); GetBiYouXuePermissionList(1); }, error: function (e) { debugger }, beforeSend: function () { $('#myachievementbody').showLoading(); } });
我用此文第三种方案: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
服务器端代码:
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 }
前端代码:
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 });
2. 利用过滤器判断请求来决定是否跨域
(1) 背景
想实现服务器端方法正常写,该返回什么就返什么,如果是JSONP请求,则返回JSONP格式,如果是普通请求,则返回不同格式。
(2) 原理
如果是jsonp请求的,如同下面这个地址:http://localhost:29492/Home/GetInfor2?myCallBack=jQuery341001790888637311383_1564124488832&userName=ypf&_=1564124488833, 第一个参数为myCallBack,如果有这个参数则证明是jsonp请求,需要拿到它的值;反之如果没有这个参数,则是普通请求,需要配置跨域策略了,才能拿到值。
在过滤器中判断,如果是jsonp请求,则将数据进行包裹进行返回,如果是普通请求,则直接返回,然后把过滤器以特性[IsJsonpCallback]形式作用在GetInfor2方法上。
过滤器代码:
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 }
服务器端代码:
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 }
前端代码:
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 });
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上看代码)

浙公网安备 33010602011771号