using MvcApp.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace MvcApp.Controllers
{
[AllowCors("http://localhost:13433", "http://localhost:13435")]
//[AllowCors]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
} public ActionResult Test()
{
var json = new { Name = "Server" };
return Json(json,JsonRequestBehavior.AllowGet);
} }
}

  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace MvcApp.Filters
{
public class AllowCorsAttribute:ActionFilterAttribute
{
private string[] _domains;
public AllowCorsAttribute()
{
//如果[AllowCors]特性标签没有带域名,那么就从配置文件中读取允许访问的域名,然后将它赋给_domains
//_domains = 这里应该是从配置文件中读出来的所有域名组成的数组
_domains = new string[] { "", "" };
}
public AllowCorsAttribute(params string[] domain)
{
_domains = domain;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var urlReferrer = filterContext.HttpContext.Request.UrlReferrer;
if (urlReferrer != null)
{
var absolutePath = urlReferrer.OriginalString;
var absolutePathFormat = absolutePath.Substring(0, absolutePath.Length - 1);
if (_domains.Contains(absolutePathFormat))
{
filterContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", absolutePathFormat);
}
}
else
{
//如果urlReferrer为空,我理解为自己本地访问(亲自测试,本地访问urlReferrer为null)
filterContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
}
filterContext.HttpContext.Response.AddHeader("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS, POST, PUT");
filterContext.HttpContext.Response.AddHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
base.OnActionExecuting(filterContext);
}
}
}

  

@{
ViewBag.Title = "Index";
} <h2>Index</h2> <script type="text/javascript">
$.ajax({
url: 'http://localhost:24102/Home/Test',
type: 'Post',
success: function (data, textStatus) {
alert(data.Name);
},
error:function(XMLHttpRequest, textStatus, errorThrown){
alert(XMLHttpRequest.state);
} })
</script>

  -------------------------------------------------------------------------------------

JSONP是一种依靠开发人员的聪明才智创造出的一种非官方跨域数据交互协议。

1、一个众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面、动态网页、web服务、WCF,只要是跨域请求,一律不准;
   2、不过我们又发现,Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有”src”这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>);
   3、于是可以判断,当前阶段如果想通过纯web端(ActiveX控件、服务端代理、属于未来的HTML5之Websocket等方式不算)跨域访问数据就只有一种可能,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理;
   4、恰巧我们已经知道有一种叫做JSON的纯字符数据格式可以简洁的描述复杂数据,更妙的是JSON还被js原生支持,所以在客户端几乎可以随心所欲的处理这种格式的数据;
   5、这样子解决方案就呼之欲出了,web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件(一般以JSON为后缀),显而易见,服务器之所以要动态生成JSON文件,目的就在于把客户端需要的数据装入进去。
   6、客户端在对JSON文件调用成功之后,也就获得了自己所需的数据,剩下的就是按照自己需求进行处理和展现了,这种获取远程数据的方式看起来非常像AJAX,但其实并不一样。
   7、为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
   如果对于callback参数如何使用还有些模糊的话,我们后面会有具体的实例来讲解。

namespace MvcApp.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
string callback = this.Request["callback"]; //获取回调函数的名称,的到showMessage
string json = "{\"name\":\"server\"}";
this.Response.Write(callback + "(" + json + ")");
return new EmptyResult();
}
}
}

  

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

  -----------MvcApp项目优化 (优化服务端)  主要是自定义一个JsonpResult类,这个类继承了JsonResult类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Script.Serialization; namespace MvcApp.Controllers
{
public class HomeController : Controller
{
public JsonpResult IndexTest()
{
return this.Jsonp(new { name = "server JsonpResult" });
}
} 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 AccessViolationException("context");
} if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) //如果不允许来自客户端的Get请求,并且请求类型是Get
{
throw new AccessViolationException();
}
var response = context.HttpContext.Response;
if (!string.IsNullOrEmpty(ContentType)) //这个ContentType是获取或设置内容的类型。它是JsonResult类中的一个属性
{
response.ContentType = ContentType; //设置响应内容的类型
}
else
{
response.ContentType = CallbackApplicationType; //设置响应内容的类型
}
if (ContentEncoding != null)
{
response.ContentEncoding = this.ContentEncoding;//设置响应内容的编码
} if (Data != null) //这个Data是JsonResult类中的一个属性
{
string buffer;
var request = context.HttpContext.Request;
var serializer = new JavaScriptSerializer();
if (request[JsonpCallbackName] != null) //获取回调函数名称(即:获取这个<script src="http://localhost:58382/home/IndexTest?callback=showMessage" type="text/javascript"></script>链接上的callback的值,即获取showMessage)
{
buffer = String.Format("{0}({1})", request[JsonpCallbackName], serializer.Serialize(Data));//首先根据callback获取获取函数名,然后传入json字符串作为函数参数
}
else
{
buffer = serializer.Serialize(Data);
}
response.Write(buffer);
}
}
} /// <summary>
/// Controller控制器类的扩展方法,即:Controller控制器下扩展一个Jsonp方法,这个方法带一个object类型的参数
/// </summary>
public static class ControllerExtension
{
public static JsonpResult Jsonp(this Controller controller, object data)
{
JsonpResult result = new JsonpResult()
{
Data = data,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
return result;
}
}
}

  

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

  

案例:二

直接通过ajax进行跨域请求数据(将dataType的值设为jsonp)
 这种方式其中本质也是和案例一是一样的。都是通过Get请求
 它最终也是通过请求 http://localhost:58382/home/Index?callback=jsonpCallback&_=1481277739025 这个地址,然后服务端拿到callback这个回调函数,然后返回 jsonpCallback({"name":"Server"}) 这样的一个函数,这样我们在本地定义的jsonpCallback函数就可以使用了。这样功能跨域就实现了

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="~/Scripts/jquery-1.8.2.js"></script>
</head>
<body>
<div> </div>
</body>
</html>
<script type="text/javascript">
$.ajax({
url: 'http://localhost:58382/home/Index', //请求的url dataType: "jsonp", //将请求类型设为值jsonp //传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonp: "callback", //服务端会通过HttpContext.Request["callback"]; 拿到jsonpCallback这个回调函数的名称 jsonpCallback: "jsonpCallback", //自定义的jsonp回调函数名称"jsonpCallback",返回的json也必须有这个函数名称 success: function (json) {
console.log(json);
alert(json.name);
},
error: function (xhr, status, error)
{ console.log(xhr); }
});
</script>

  

<pre snippet_file_name="blog_20161209_5_7492657" code_snippet_id="2039637"></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>

  

跨域访问MVC的更多相关文章

  1. Angular2中对ASP.NET MVC跨域访问

    应用场景 项目开发决定使用angular2进行前后端分离开发,由我负责后端服务的开发,起初选择的是web api进行开发.对跨域访问通过API中间件+过滤器对跨域访问进行支持.开发一段后,通知需要移植 ...

  2. 【转载】ASP.NET MVC设置允许跨域访问

    默认情况下,浏览器端发送Ajax请求一般被禁止跨域访问,如A域名网站访问B域名网站的请求会被终止,在ASP.NET MVC项目中,我们可以配置相应的设置项,允许网站的接口跨域访问,主要需要设置Acce ...

  3. Spring MVC 4.2 CORS 跨域访问

    跨站 HTTP 请求(Cross-site HTTP request)是指发起请求的资源所在域不同于该请求所指向资源所在的域的 HTTP 请求.比如说,域名A(http://domaina.examp ...

  4. ASP.NET MVC & WebApi 中实现Cors来让Ajax可以跨域访问 (转载)

    什么是Cors? CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing).它允许浏览器向跨源服务器,发出XMLHttpReq ...

  5. System.Web.Http.Cors配置跨域访问的两种方式

    System.Web.Http.Cors配置跨域访问的两种方式 使用System.Web.Http.Cors配置跨域访问,众多大神已经发布了很多文章,我就不在详细描述了,作为小白我只说一下自己的使用心 ...

  6. ajax跨域访问 java controller 和 cxf(webservice) 配置方式(CORS)

    1. controller跨域访问,配置方式 重点在这里: <mvc:cors> <mvc:mapping path="/*" allowed-origins=& ...

  7. Ajax跨域访问解决办法

    方法1. jsonp实现ajax跨域访问示例 jsp代码: <body> <input type="button" onclick="testJsonp ...

  8. 跨域访问之JSONP

    跨域 在平常的工作中常常会遇到A站点的需要访问B站点的资源. 这时就产生了跨域访问. 跨域是指从一个域名的网页去请求另一个域名的资源.浏览器遵循同源策略,不允许A站点的Javascript 读取B站点 ...

  9. SpringMvc支持跨域访问,Spring跨域访问,SpringMvc @CrossOrigin 跨域

    SpringMvc支持跨域访问,Spring跨域访问,SpringMvc @CrossOrigin 跨域 >>>>>>>>>>>> ...

随机推荐

  1. 排序---希尔排序Java

    希尔排序 插入排序的一种又称“缩小增量排序”,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法. 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减 ...

  2. 去参加了十四届D2前端大会~

    朋友喊我去一起去d2,原来一直在加班,没有想去的动力,后来业务上线,幸运的入手了别人转的一张票(也不便宜啊)- 讲了五个挑战 端侧渲染体系的重塑,从PC时代到无线时代,再到未来的IOT时代,在渲染方面 ...

  3. 剑指offer:链表中环的入口结点

    题目描述: 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 思路分析: 这道题首先需要判断链表是否存在环,很快就能想到用快慢指针来判断. 由于快慢指针的相遇位置并不一定为链 ...

  4. idea docker docker-compose发布springboot站点到tomcat

    允许docker被远程访问 见:https://www.cnblogs.com/wintersoft/p/10921396.html 教程:https://spring.io/guides/gs/sp ...

  5. Unity内存优化之视频讲解

    视频为中文讲解,mp4格式,大小3.05GB 目录   扫码时备注或说明中留下邮箱 付款后如未回复请至https://shop135452397.taobao.com/ 联系店主

  6. Unity3D Substance designer Sub 欧洲小镇场景制作视频教程 中文字幕

    大小6.53G,中文字幕 扫码时备注或说明中留下邮箱 付款后如未回复请至https://shop135452397.taobao.com/ 联系店主

  7. easyui 如何为datagrid添加自定义列属性(如:width,align,editor)

    我在实际业务需要为datagrid添加一个自定义属性 原先的datagrid列属性包括:title.width.align.formattter.editor等 我们可以通过datagrid的一个方法 ...

  8. uboot中工具buildman的用法

    1. buildman简介 uboot源码中维护的一款多线程编译测试工具 2. buildman的用法 2.1 进入uboot的源码目录 $ cd <path of uboot> 2.2 ...

  9. openresty开发系列38--通过Lua+Redis 实现动态封禁IP

    openresty开发系列38--通过Lua+Redis 实现动态封禁IP 一)需求背景为了封禁某些爬虫或者恶意用户对服务器的请求,我们需要建立一个动态的 IP 黑名单.对于黑名单之内的 IP ,拒绝 ...

  10. Spring MVC -- JSP标准标签库(JSTL)

    JSP标准标签库(JavaServer Pages Standard Tag Library,JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能.JSTL支持通用的.结构化的任务,比如迭 ...