1:原理

在js中,XMLHttpRequest是不能请求不同域的数据,但是script标签却可以,所以可以用script标签实现跨域请求。具体是定义一个函数,例如jsonp1234,请求不同域的url时带上函数名,例如:http://otherdomain.com/index?callback=jsonp1234,然后服务端根据callback获取这个函数名,然后传入json字符串作为函数参数。

2:实现

http://localhost:62203/home/index页面代码如下

@{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script>
function showMessage(result) {
alert(result.name)
}
</script>
<script src="http://localhost:16308/home/index?callback=showMessage" type="text/javascript"></script>
</head>
<body>
<div>
</div>
</body>
</html>

主要是这句  

<script src="http://localhost:16308/home/index?callback=showMessage" type="text/javascript"></script>,

可以看到,访问的是不同的站点,并且callback的参数值为showMessage,

http://localhost:16308/home/index代码如下

public ActionResult Index()
{
string callback = this.Request["callback"];
string json="{\"name\":\"server\"}";
this.Response.Write(callback + "(" + json + ")");
return new EmptyResult();
}

根据callback获取函数名,然后将json字符串作为函数参数。

访问页面http://localhost:62203/home/index,效果如下

可见,站点localhost:62203从站点localhost:16308获取到了数据。

但是我们看服务端的实现,这也太不美观,也比较麻烦。

public ActionResult Index()
{
string callback = this.Request["callback"];
string json="{\"name\":\"server\"}";
this.Response.Write(callback + "(" + json + ")");
return new EmptyResult();
}

我们想要的是调用一个方法,就能实现跨域了,那如何实现呢。看到Controller有个this.Json方法,类型是JsonResult,我们可以参考这个类。定义一个类JsonpResult,派生于JsonResult,在ExecuteResult方法根据callback获取函数名,然后传入json字符串作为函数参数。

public class JsonpResult : JsonResult
{
public static readonly string JsonpCallbackName = "callback";
public static readonly string CallbackApplicationType = "application/json"; public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if ((JsonRequestBehavior == JsonRequestBehavior.DenyGet) &&
String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException();
}
var response = context.HttpContext.Response;
if (!String.IsNullOrEmpty(ContentType))
response.ContentType = ContentType;
else
response.ContentType = CallbackApplicationType;
if (ContentEncoding != null)
response.ContentEncoding = this.ContentEncoding;
if (Data != null)
{
String buffer;
var request = context.HttpContext.Request;
var serializer = new JavaScriptSerializer();
if (request[JsonpCallbackName] != null)
buffer = String.Format("{0}({1})", request[JsonpCallbackName], serializer.Serialize(Data));//首先根据callback获取获取函数名,然后传入json字符串作为函数参数
else
buffer = serializer.Serialize(Data);
response.Write(buffer);
}
}
}

JsonpResult类有了,但是想在Controller这样使用this.Jsonp,所以为Controller类定义一个扩展方法,

public static class ControllerExtension
{
public static JsonpResult Jsonp(this Controller controller, object data)
{
JsonpResult result = new JsonpResult()
{
Data = data,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
return result;
}
}

这是在Controller就可以直接使用this.Jsonp了,把跨域服务端的代码改下

public ActionResult Index()
{
return this.Jsonp(new { name = "server JsonpResult" });
}

相比上面那个简洁多了

再次打开http://localhost:62203/home/index

同样,站点localhost:62203从站点localhost:16308获取到了数据,和上面的一样

ASP.NET MVC 定义JsonpResult实现跨域请求的更多相关文章

  1. MVC 定义JsonpResult实现跨域请求

    MVC 定义JsonpResult实现跨域请求 1:原理 在js中,XMLHttpRequest是不能请求不同域的数据,但是script标签却可以,所以可以用script标签实现跨域请求.具体是定义一 ...

  2. spring mvc \ spring boot 允许跨域请求 配置类

    用@Component 注释下,随便放个地方就可以了 package com.chinaws.wsarchivesserver.core.config; import org.springframew ...

  3. asp.net mvc 安全测试漏洞 "跨站点请求伪造" 问题解决

    IBM Security Appscan漏洞筛查-跨站请求伪造,该漏洞的产生,有多种情况: 1.WebApi的跨站请求伪造,需要对WebApi的请求头部做限制(此文不做详细介绍): 2.MVC Act ...

  4. asp.net mvc web api 可跨域方法

    1.直接修改 web.config ,不过这是针对所有 Action. <location path="Sample.txt"> <system.webServe ...

  5. ASP.NET Core 利用中间件支持跨域请求

    方法1: 在Startup的ConfigureServices()中添加services.AddCors()在Startup的Configure()中添加app.UseCors(); 保证其在app. ...

  6. ASP.NET MVC 实现AJAX跨域请求方法《1》

    ASP.NET MVC 实现AJAX跨域请求的两种方法 通常发送AJAX请求都是在本域内完成的,也就是向本域内的某个URL发送请求,完成部分页面的刷新.但有的时候需要向其它域发送AJAX请求,完成数据 ...

  7. ASP.NET MVC 实现AJAX跨域请求的两种方法

    通常发送AJAX请求都是在本域内完成的,也就是向本域内的某个URL发送请求,完成部分页面的刷新.但有的时候需要向其它域发送AJAX请求,完成数据的加载,例如Google. 在ASP.NET MVC 框 ...

  8. ASP.NET MVC 实现 AJAX 跨域请求

    ASP.NET MVC 实现AJAX跨域请求的两种方法 和大家分享下Ajax 跨域的经验,之前也找了好多资料,但是都不行,后来看到个可行的修改了并测试下 果然OK了   希望对大家有所帮助! 通常发送 ...

  9. 解决ajax跨域请求问题

    自己做网站的时候,经常遇到跨域问题,下面是平时多次实践总结出的解决方法,大家有什么更好的思路,可以相互交流下~ XMLHttpRequest cannot load http://www.imooc. ...

随机推荐

  1. AIX操作oracle

    oracle:出现下述错误,无法连接用户. ORA-01034: ORACLE not available ORA-27101: shared memory realm does not exist ...

  2. winform 窗体关闭按钮禁用、不显示最大化、最小化、关闭按钮 分类: WinForm 2014-12-22 16:09 82人阅读 评论(0) 收藏

    关闭按钮禁用: (1) FormClosing事件 private void Main_FormClosing(object sender, FormClosingEventArgs e) {     ...

  3. 【原创】javascript——事件思维导图

  4. Sysstat LINUX工具包址

    http://sebastien.godard.pagesperso-orange.fr/

  5. Realm Configuration HOW-TO--官方

    来源:https://secure.gettinglegaldone.com/docs/realm-howto.html Quick Start This document describes how ...

  6. Java基础知识强化13:Java中单例模式案例使用(懒汉式)

    1.古往今来历史上皇帝通常只有一人.为了保证其唯一性,古人采用增加"防伪标识"的办法,如玉玺.更为简单的办法就是限制皇帝的创建.本案例中就是使用单例模式从而保证皇帝的唯一性.实例运 ...

  7. [iOS 开发]UITableView第一行显示不完全

    造成这个问题的原因可能有两个: 1. UITableView的contentOffset属性的改变: 2. MJRefresh调用两次headerEndRefreshing会造成刷新后UITableV ...

  8. 关于弹出层(iframe)时刷新页面的js

    [javascript] view plaincopyprint? iframe弹出子页面刷新父页面iframe parent.location.reload(); [javascript] view ...

  9. OSI七层模型理解

    物理层功能1,为数据端设备提供传送数据的通路 功能2,传输数据 接口.传输介质.信号的传输.网络设备 有线介质:双绞线(普通的网线),光纤. 无线介质:无线电.微波.激光.红外线. 例如手机.电视接收 ...

  10. SQL拾遗

    前两天同事问了个SQL问题,有个出价记录表[针对不同拍品出价],每个人都可以多次出价,要查下哪些拍品出价最高的人和出价次高的人是同一个人的记录,当时写了下面的SQL,今天先记下了,欢迎补充新的查询方式 ...