WebAPI的跨域访问CORS三种方法
跨域访问:
JSONP的原理利用<script>没有跨域访问的限制,利用<script>的src跨域访问api,api会根据数据把json包装在一个js里面,这样跨域的客户端拿到json的包装(json padding)就会调用本地的函数解析数据。总结来说就是利用两点1、浏览器的跨域限制其实是接收了数据,但限制使用跨域数据。2是利用script标签可以跨域回调的功能
1、JSONP——js
api服务端
public HttpResponseMessage GetAllContacts(string callback)
{
Contact[] contacts = new Contact[]
{
new Contact{ Name="张三", PhoneNo="", EmailAddress="zhangsan@gmail.com"},
new Contact{ Name="李四", PhoneNo="", EmailAddress="lisi@gmail.com"},
new Contact{ Name="王五", PhoneNo="", EmailAddress="wangwu@gmail.com"},
};
JavaScriptSerializer serializer = new JavaScriptSerializer();
string content = string.Format("{0}({1})", callback, serializer.Serialize(contacts));
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(content, Encoding.UTF8, "text/javascript")
};
}
客户端
<head>
<title>联系人列表</title>
<script type="text/javascript" src="@Url.Content("~/scripts/jquery-1.10.2.js")"></script>
<script type="text/javascript">
function listContacts(contacts)
{
$.each(contacts, function (index, contact) {
var html = "<li><ul>";
html += "<li>Name: " + contact.Name + "</li>";
html += "<li>Phone No:" + contact.PhoneNo + "</li>";
html += "<li>Email Address: " + contact.EmailAddress + "</li>";
html += "</ul>";
$("#contacts").append($(html));
});
}
</script>
</head>
<body>
<ul id="contacts"></ul>
<script type="text/javascript" src="http://localhost:3721/api/contacts?callback=listContacts"></script>
</body>
</html>
2、JSONP——JsonMediaTypeFormatter
服务端定义类:
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{ }
}
注册到Global中
GlobalConfiguration.Configuration.Formatters.Insert(0, new JsonpMediaTypeFormatter());
直接返回数据让系统自动协商优先使用
客户端:
$(function ()
{
$.ajax({
type: "GET",
url: "http://localhost:3721/api/contacts",
dataType: "jsonp",
success: listContacts
});
}); function listContacts(contacts) {
$.each(contacts, function (index, contact) {
var html = "<li><ul>";
html += "<li>Name: " + contact.Name + "</li>";
html += "<li>Phone No:" + contact.PhoneNo + "</li>";
html += "<li>Email Address: " + contact.EmailAddress
+ "</li>";
html += "</ul>";
$("#contacts").append($(html));
});
}
3、Microsoft AsRNET Web API2Cross-Origin support
原理:利用http的响应包标识Header;Access-Control-Allow-Origin等等标签标识允许跨域访问
Install-Package Microsoft.AspNet.WebApi.Cors
开启方法:
GlobalConfiguration.Configuration.EnableCors();
或在webapiconfig注册路由里开启
config.EnableCors();
api使用特性:
[EnableCors("http://localhost:9527","*","*")]
做全局配置Global/WebApiConfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var cors = new EnableCorsAttribute("www.clientA.com", "*", "*");
config.EnableCors(cors);
// ...
}
}
也可以只针对Controller或者Action做配置
[EnableCors(origins: "http://www.ClientA.com", headers: "*", methods: "*")]
public class ItemsController : ApiController
{
public HttpResponseMessage GetAll() { ... }
[EnableCors(origins: "http://www.ClientB.com", headers: "*", methods: "*")]
public HttpResponseMessage GetItem(int id) { ... }
public HttpResponseMessage Post() { ... } [DisableCors]
public HttpResponseMessage PutItem(int id) { ... }
}
WebAPI的跨域访问CORS三种方法的更多相关文章
- Ajax实现跨域访问的三种方法
转载自:http://www.jb51.net/article/68424.htm 一.什么是跨域 我们先回顾一下域名地址的组成: http:// www . google : 8080 / scri ...
- Ajax--跨域访问的三种方法
一.什么是跨域 我们先回顾一下域名地址的组成: / script/jquery.js http:// (协议号) www (子域名) google (主域名) (端口号) script/jquer ...
- Ajax实现跨域访问的两种方法
调程序时遇到"已拦截跨源请求:同源策略禁止读取位于--的远程资源",这是因为通过ajax调用其他域的接口会有跨域问题. 解决方法如下: 方法一:服务器端(PHP)设置header头 ...
- jQuery 跨域访问的三种方式 No 'Access-Control-Allow-Origin' header is present on the reque
问题: XMLHttpRequest cannot load http://v.xxx.com. No 'Access-Control-Allow-Origin' header is present ...
- System.Web.Http.Cors配置跨域访问的两种方式
System.Web.Http.Cors配置跨域访问的两种方式 使用System.Web.Http.Cors配置跨域访问,众多大神已经发布了很多文章,我就不在详细描述了,作为小白我只说一下自己的使用心 ...
- asp.net core webapi之跨域(Cors)访问
这里说的跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被当作 ...
- 解决ajax跨域问题的一种方法
解决ajax跨域问题的一种方法 前后端分离经常用json来传输数据,比较常见的问题就有ajax跨域请求的错误问题,这里是我的一种解决方法: 在java中加入如下的注解类: import org.spr ...
- .Net WebApi 支持跨域访问使用 Microsoft.AspNet.WebApi.Cors
首先导入Cors库,通过程序包管理控制台导入 Install-Package Microsoft.AspNet.WebApi.Cors 引用库之后,我们需要进行简单的配置. 现在WebApiConfi ...
- 使用Cors后台设置WebAPI接口跨域访问
昨天根据项目组前端开发工程师反映,在浏览器端无法直接使用ajax访问后台接口获取数据,根据他的反映,我查阅了相关跨域的解决方案: 一:使用jsonP,但是jsonP只能使用GET请求,完全不符合我项目 ...
随机推荐
- MPD软件工作坊北京站:技术创新与研发效率带来的前沿思考
在新技术层出不穷.不断迭代的当下,多数企业都在面临技术能力提升,认知升级等问题.面对技术企业的研发环节,为什么你的效率总是提不上来?都在寻找创新的技术领域,为何别人总能抢占先机?提升自己的研发竞争力, ...
- MySQL之多表查询一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习
MySQL之多表查询 阅读目录 一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习 一 介绍 本节主题 多表连接查询 复合条件连接查询 子查询 首先说一下,我们写项目一般都会建 ...
- [No0000EB]C# 数组(Array)
数组是一个存储相同类型元素的固定大小的顺序集合.数组是用来存储数据的集合,通常认为数组是一个同一类型变量的集合. 声明数组变量并不是声明 number0.number1.....number99 一个 ...
- OpenGL开发学习指南二(glfw+glad)
版权声明:本文为博主原创文章,未经博主允许不得转载.blog.liujunliang.com.cn https://blog.csdn.net/qq_33747722/article/details/ ...
- iOS开发使用pdf切图
把pdf资源拖到Assets.xcassets里面, 打开最右边的按钮, scales选择single scale就可以像以前一样使用了: [UIImage imageName:@"xxx ...
- kafka后台启动的命令
kafka如果直接启动会出现问题,就是信息会打印在控制台,就会出现在控制台. 然后关闭窗口,kafka随之关闭,然后启动以下的命令就可以实现. ./kafka-server-start.sh ../c ...
- springboot 整合swagger-ui
一.添加maven依赖 <dependency> <groupId>io.springfox</groupId> <artifactId>springf ...
- Python开发【模块】:aiohttp(一)
AIOHTTP 用于asyncio和Python的异步HTTP客户端/服务器 主要特点: 支持客户端和HTTP服务器. 支持服务器WebSockets和 客户端WebSockets开箱即用,没有回调地 ...
- bzoj 2563 [2012国家集训队Round 1 day2] 阿狸和桃子的游戏 贪心
正解:贪心 解题报告: 链接在这儿! 知道解法之后会jio的好像很简单的样子……其实挺难想到的QAQ 不过大佬讲了方法之后还是懂了 有一个很神仙的想法就是,你可以理解为每个点周围的边都有半个是自己的, ...
- 【python-opencv】图像直方图
图像直方图使用到:python-opencv.matplotlib.numpy def plot_demo(image): print(len(image.ravel())) #统计image3通道的 ...