跨域访问:

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三种方法的更多相关文章

  1. Ajax实现跨域访问的三种方法

    转载自:http://www.jb51.net/article/68424.htm 一.什么是跨域 我们先回顾一下域名地址的组成: http:// www . google : 8080 / scri ...

  2. Ajax--跨域访问的三种方法

    一.什么是跨域 我们先回顾一下域名地址的组成: / script/jquery.js  http:// (协议号) www  (子域名) google (主域名) (端口号) script/jquer ...

  3. Ajax实现跨域访问的两种方法

    调程序时遇到"已拦截跨源请求:同源策略禁止读取位于--的远程资源",这是因为通过ajax调用其他域的接口会有跨域问题. 解决方法如下: 方法一:服务器端(PHP)设置header头 ...

  4. 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 ...

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

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

  6. asp.net core webapi之跨域(Cors)访问

    这里说的跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被当作 ...

  7. 解决ajax跨域问题的一种方法

    解决ajax跨域问题的一种方法 前后端分离经常用json来传输数据,比较常见的问题就有ajax跨域请求的错误问题,这里是我的一种解决方法: 在java中加入如下的注解类: import org.spr ...

  8. .Net WebApi 支持跨域访问使用 Microsoft.AspNet.WebApi.Cors

    首先导入Cors库,通过程序包管理控制台导入 Install-Package Microsoft.AspNet.WebApi.Cors 引用库之后,我们需要进行简单的配置. 现在WebApiConfi ...

  9. 使用Cors后台设置WebAPI接口跨域访问

    昨天根据项目组前端开发工程师反映,在浏览器端无法直接使用ajax访问后台接口获取数据,根据他的反映,我查阅了相关跨域的解决方案: 一:使用jsonP,但是jsonP只能使用GET请求,完全不符合我项目 ...

随机推荐

  1. okvis论文解读

    C. Keypoint Matching and Keyframe Selection 我们的处理流程采用定制的多尺度SSE优化Harris角点检测器与BRISK描述符提取相结合[12].检测器通过逐 ...

  2. ==和equal()的区别

    “==”比较的是对象引用的地址相不相同 “equal()”比较的是内容是否相等

  3. [No000011D].NETCORE1/19-.NET Core 指南

    .NET Core 是一个通用开发平台,由 Microsoft 和 GitHub 上的 .NET 社区共同维护.跨平台的,支持 Windows.macOS 和 Linux,并且可用于设备.云和嵌入式/ ...

  4. nethogs 查看 Linux 进程的网络使用

    有时候我们客户会发现服务器或 VPS 网络慢,进一步发现大量带宽被占用,一些客户到这里为止就不知道怎么办了.有什么简单办法能找出哪个程序(或者进程)占用了带宽呢?Linux 监控流量的小工具不少,如 ...

  5. 转:cookie.setPath()用法

    原文地址:cookie.setPath()的用法 正常的cookie只能在一个应用中共享,即一个cookie只能由创建它的应用获得. 1.可在同一应用服务器内共享方法:设置cookie.setPath ...

  6. LeetCode 893 Groups of Special-Equivalent Strings 解题报告

    题目要求 You are given an array A of strings. Two strings S and T are special-equivalent if after any nu ...

  7. LeetCode 832 Flipping an Image 解题报告

    题目要求 Given a binary matrix A, we want to flip the image horizontally, then invert it, and return the ...

  8. activemq安装使用教程

    一.下载安装 下载地址:http://activemq.apache.org/activemq-5158-release.html 然后解压即可,apache的东西解压后就可以使用了. 二.启动 在安 ...

  9. Python开发【笔记】:asyncio 定时器

    asyncio 定时器 实现: import asyncio class Timer: def __init__(self, timeout, callback): self._timeout = t ...

  10. webpack浅析~

    1.webpack打包原理: 把所有依赖打包成一个 bundle.js 文件,通过代码分割成单元片段并按需加载. 2.webpack的优势: ①.webpack 是以 commonJS 的形式来书写脚 ...