使Asp.net WebApi支持JSONP和Cors跨域访问
1.服务端处理
同源策略(Same Origin Policy)的存在导致了“源”自A的脚本只能操作“同源”页面的DOM,“跨源”操作来源于B的页面将会被拒绝。同源策略以及跨域资源共享在大部分情况下针对的是Ajax请求。同源策略主要限制了通过XMLHttpRequest实现的Ajax请求,如果请求的是一个“异源”地址,浏览器将不允许读取返回的内容。JSONP是一种常用的解决跨域资源共享的解决方案,现在我们利用ASP.NET Web API自身的扩展性提供一种“通用”的JSONP实现方案。
我们通过继承JsonMediaTypeFormatter定义了如下一个JsonpMediaTypeFormatter类型。它的只读属性Callback代表JavaScript回调函数名称,改属性在构造函数中指定。在重写的方法WriteToStreamAsync中,对于非JSONP调用(回调函数不存在),我们直接调用基类的同名方法对响应对象实施针对JSON的序列化,否则调用WriteToStream方法将对象序列化后的JSON字符串填充到JavaScript回调函数中。
我们重写了GetPerRequestFormatterInstance方法,在默认情况下,当ASP.NET Web API采用内容协商机制选择出与当前请求相匹配的MediaTypeFormatter后,会调用此方法来创建真正用于序列化响应结果的MediaTypeFormatter对象。在重写的这个GetPerRequestFormatterInstance方法中,我们尝试从请求的URL中得到携带的JavaScript回调函数名称,即一个名为“callback”的查询字符串。如果回调函数名不存在,则直接返回自身,否则返回据此创建的JsonpMediaTypeFormatter对象。
1.重写JsonMediaTypeFormatter处理JSONP请求
public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter
{
public string Callback { get; private set; } public JsonpMediaTypeFormatter(string callback = null)
{
this.Callback = callback;
} public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
if (string.IsNullOrEmpty(this.Callback))
{
return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
}
try
{
this.WriteToStream(type, value, writeStream, content);
return Task.FromResult<AsyncVoid>(new AsyncVoid());
}
catch (Exception exception)
{
TaskCompletionSource<AsyncVoid> source = new TaskCompletionSource<AsyncVoid>();
source.SetException(exception);
return source.Task;
}
} private void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
{
JsonSerializer serializer = JsonSerializer.Create(this.SerializerSettings);
using (StreamWriter streamWriter = new StreamWriter(writeStream, this.SupportedEncodings.First()))
using (JsonTextWriter jsonTextWriter = new JsonTextWriter(streamWriter) { CloseOutput = false })
{
jsonTextWriter.WriteRaw(this.Callback + "(");
serializer.Serialize(jsonTextWriter, value);
jsonTextWriter.WriteRaw(")");
}
} public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
if (request.Method != HttpMethod.Get)
{
return this;
}
string callback;
if (request.GetQueryNameValuePairs().ToDictionary(pair => pair.Key,
pair => pair.Value).TryGetValue("callback", out callback))
{
return new JsonpMediaTypeFormatter(callback);
}
return this;
} [StructLayout(LayoutKind.Sequential, Size = )]
private struct AsyncVoid
{ }
}
2.在网站启动注册
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
//注册JSOPN提交处理
GlobalConfiguration.Configuration.Formatters.Insert(, new JsonpMediaTypeFormatter());
}
}
2.客户端实例
//使用Cors方式提交
$.get(apiUrl.getTwo("TestTwo"), {
name: '张三'
}, function (data) {
alert(data);
}); //使用Jsonp方式提交
$.ajax({
data: {
name: 'zhangsan'
},
url: apiUrl.getTwo('TestTwo'),
dataType: 'jsonp',
success: function (data) {
alert(data);
},
error: function (XMLRequest, textStatus) {
console.info(XMLRequest);
console.info(textStatus);
alert('失败');
}
});
分别的相应结果:


使Asp.net WebApi支持JSONP和Cors跨域访问的更多相关文章
- asp.net webAPI POST方法的CORS跨域问题
端口不同会判断为不同域 Method Not Allowed . web.config中设定·customHeaders 错误变化为 原因‘ post方法使用前会有一次OPTION方法的请求’ 解决: ...
- Asp.Net WebApi 启用CORS跨域访问指定多个域名
1.后台action指定 EnableCors指定可访问的域名多个,使用逗号隔开 //支持客户端凭据提交,指定多个域名,使用逗号隔开 [EnableCors("http://localhos ...
- Asp.Net WebApi+Microsoft.AspNet.WebApi.Core 启用CORS跨域访问
WebApi中启用CORS跨域访问 1.安装 Nugget包Microsoft.AspNet.WebApi.Cors This package contains the components to e ...
- jsonp与cors跨域的一些理解(转)
CORS其实出现时间不短了,它在维基百科上的定义是:跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源.而这种访问是被同源策略所禁止的. ...
- SpringBoot学习(3)-SpringBoot添加支持CORS跨域访问
SpringBoot学习(3)-SpringBoot添加支持CORS跨域访问 https://blog.csdn.net/yft_android/article/details/80307672
- Spring Boot 2中对于CORS跨域访问的快速支持
原文:https://www.jianshu.com/p/840b4f83c3b5 目前的程序开发,大部分都采用前后台分离.这样一来,就都会碰到跨域资源共享CORS的问题.Spring Boot 2 ...
- spring boot / cloud (六) 开启CORS跨域访问
spring boot / cloud (六) 开启CORS跨域访问 前言 什么是CORS? Cross-origin resource sharing(跨域资源共享),是一个W3C标准,它允许你向一 ...
- Springboot CORS跨域访问
Springboot CORS跨域访问 什么是跨域 浏览器的同源策略限制: 它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础 ...
- jsonp与cors跨域的一些理解
浏览器的同源策略,即是浏览器之间要隔离不同域的内容,禁止互相操作. 比如,当你打开了多个网站,如果允许多个网站之间互相操作,那么其中一个木马网站就可以通过这种互相操作进行一系列的非法行为,获取你在各个 ...
随机推荐
- mysql 5.5 升级到 mysql 5.6
目前MySQL数据库软件升级到5..26版本,主要有两种方法.一种是停机升级,即在现有环境下先停止数据库,然后升级数据库软件版本和数据库版本:另外一种是采用不停机的主从升级(master--slave ...
- regular expression (php函数)
1. 正则表达式是一种字符串搜索和匹配的工具 2. php中常用正则表达式函数 preg_match($pattern, $subject) preg_match_all($pattern, $sub ...
- Number对象
<script type="text/javascript"> /* Number对象. 创建Number对象的方式: 方式1: var 变量= new Number( ...
- iOS开发之UIWebView自动滑动到顶部-备
但可以通过subview来操作. 通常用UIWebView加载网页,有时候需要点击一个按钮,或者页面的某个部位,使页面自动滚动到顶部,但是UIWebView不像UIScrollView那么方便. ...
- 剑指offer之关于整数的处理
首先是整数次方的处理 在这处理的时候有几个细节主义处理 1.当指数是负数的时候 2.当指数式0的时候 3.当不满足条件的时候要抛出异常 再一个就是常用的将一个树化为二进制的形式,或者是求整数的幂或者矩 ...
- libCurl的C++引用
I believe I have gotten LibCurl to work with Visual Studio 2013 now. Persistence ftw! Although, afte ...
- Linux read语法及浅析
read命令 -n(不换行) -p(提示语句) -n(字符个数) -t(等待时间) -s(不回显) 1.基本读取read命令接收标准输入(键盘)的输入,或其他文件描述符的输入(后面在说).得到输入后, ...
- opencv 图像仿射变换 计算仿射变换后对应特征点的新坐标 图像旋转、缩放、平移
常常需要最图像进行仿射变换,仿射变换后,我们可能需要将原来图像中的特征点坐标进行重新计算,获得原来图像中例如眼睛瞳孔坐标的新的位置,用于在新得到图像中继续利用瞳孔位置坐标. 仿射变换在:http:// ...
- SDL2.0 学习笔记-1 windows下的第一个测试程序
SDL全称是Simple DirectMedia Layer,是一个开源的.跨平台(win32,linux,mac)的多媒体开发c语言库. 官方网站 http://www.libsdl.org/ 第一 ...
- 【转】BT5无法找到软件安装包(提供可用的BT更新源)
像我这种一般想起才玩玩BT5的人,跟不上讯息的变化. 偶尔想尝试某个实验,然后去安装,发现提示无法找到软件安装包. 这个时候,应该注意到,现在已经从BT5到kali了,假如想我这种人,肯定比较少留意软 ...