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跨域访问的更多相关文章

  1. asp.net webAPI POST方法的CORS跨域问题

    端口不同会判断为不同域 Method Not Allowed . web.config中设定·customHeaders 错误变化为 原因‘ post方法使用前会有一次OPTION方法的请求’ 解决: ...

  2. Asp.Net WebApi 启用CORS跨域访问指定多个域名

    1.后台action指定 EnableCors指定可访问的域名多个,使用逗号隔开 //支持客户端凭据提交,指定多个域名,使用逗号隔开 [EnableCors("http://localhos ...

  3. Asp.Net WebApi+Microsoft.AspNet.WebApi.Core 启用CORS跨域访问

    WebApi中启用CORS跨域访问 1.安装 Nugget包Microsoft.AspNet.WebApi.Cors This package contains the components to e ...

  4. jsonp与cors跨域的一些理解(转)

    CORS其实出现时间不短了,它在维基百科上的定义是:跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源.而这种访问是被同源策略所禁止的. ...

  5. SpringBoot学习(3)-SpringBoot添加支持CORS跨域访问

    SpringBoot学习(3)-SpringBoot添加支持CORS跨域访问 https://blog.csdn.net/yft_android/article/details/80307672

  6. Spring Boot 2中对于CORS跨域访问的快速支持

    原文:https://www.jianshu.com/p/840b4f83c3b5 目前的程序开发,大部分都采用前后台分离.这样一来,就都会碰到跨域资源共享CORS的问题.Spring Boot 2 ...

  7. spring boot / cloud (六) 开启CORS跨域访问

    spring boot / cloud (六) 开启CORS跨域访问 前言 什么是CORS? Cross-origin resource sharing(跨域资源共享),是一个W3C标准,它允许你向一 ...

  8. Springboot CORS跨域访问

    Springboot CORS跨域访问 什么是跨域 浏览器的同源策略限制: 它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础 ...

  9. jsonp与cors跨域的一些理解

    浏览器的同源策略,即是浏览器之间要隔离不同域的内容,禁止互相操作. 比如,当你打开了多个网站,如果允许多个网站之间互相操作,那么其中一个木马网站就可以通过这种互相操作进行一系列的非法行为,获取你在各个 ...

随机推荐

  1. 武汉科技大学ACM :1007: 华科版C语言程序设计教程(第二版)习题7.10

    Problem Description 输入n(n<100)个字符串,每个字符串长度不超过1000,将他们按字典顺序输出. Input 多组测试样例. 每组第一行有一个整数n表示有n个字符串. ...

  2. 开发ContentProvider的步骤

    开发ContentProvider的步骤如下: 1.编写一个类,该类必须继承自ContentProvider. 2.实现ContentProvider类中的所有抽象方法:insert() delete ...

  3. Ubuntu 13.10 Mono安装历程

    这两天捣鼓一下Mono,记录一下自己所遇到的问题,已经解决办法 首先,先打开gnome-terminal 1. 先更新的一下系统 sudo apt-get update sudo apt-get up ...

  4. SQL Server 触发器(转)

    触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动调用执行的.而存储过程可以通过存储过程的名称被调用. Ø 什么是触发器 触发器对表进行插入.更新.删 ...

  5. Ajax 技术原理(转)

    Ajax 技术原理 2010-01-04 原文出处:http://www.nowamagic.net/ajax/ajax_AjaxPrinciple.php 在写这篇文章之前,曾经写过一篇关于AJAX ...

  6. 第几天 AC 杭电

    第几天? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  7. 重构遗留程序的一次案例学习(java程序)

    遗留代码经常是腐臭的,每个优秀的开发者都想把它重构.而进行重构的一个理想的先决条件是,它应该包含一组单元测试用例,以避免产生回归缺陷.但是为遗留代码编写单元测试可不是件容易的事,因为它经常是一团糟.要 ...

  8. 为什么我要使用一个20年前的IBM老键盘

    为什么我要使用一个20年前的IBM老键盘 发表在 心得体会 | 3条评论 几天前,我在网上发了一张图片,想炫耀了一下我的新MacBook Pro笔记本强悍的多屏功能.没人感兴趣.但图上的那个老键盘却得 ...

  9. quartz2.2.1-测试02-通过servlet动态修改定时任务运行时间

    /* * To change this license header, choose License Headers in Project Properties. * To change this t ...

  10. weblogic使用脚本部署

    --本机 (/common/bin/wlst.sh (2)connect('weblogic','weblogic1','t3://localhost:7001') (3)progress=deplo ...