跨域访问:

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. 树剖||树链剖分||线段树||BZOJ4034||Luogu3178||[HAOI2015]树上操作

    题面:P3178 [HAOI2015]树上操作 好像其他人都嫌这道题太容易了懒得讲,好吧那我讲. 题解:第一个操作和第二个操作本质上是一样的,所以可以合并.唯一值得讲的点就是:第二个操作要求把某个节点 ...

  2. KONE-FLOW Vistor Key

    WELCOME TO KONE

  3. CSP 通信顺序进程

    communicating sequential processes CSP 通信顺序进程 C.A.R.Hoare 1979 CSP是一种用来描述并行系统交互模式的形式语言,最早由C.A.R.Hoar ...

  4. 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗? 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现! 是否有一个全局视角来查看系统的运行状况? 有什么办法可以监控到JVM的实时运行状态?

    https://alibaba.github.io/arthas/ Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱. 当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决 ...

  5. A pointer is a variable whose value is the address of another variable 指针 null pointer 空指针 内存地址0 空指针检验

    小结: 1.指针的实际值为代表内存地址的16进制数: 2.不同指针的区别是他们指向的变量.常量的类型: https://www.tutorialspoint.com/cprogramming/c_po ...

  6. [daily][centos] redhat增加扩展仓库

    https://rpmfusion.org/Configuration sudo yum localinstall --nogpgcheck https://download1.rpmfusion.o ...

  7. 转:Java中子类是否可以继承父类的static变量和方法而呈现多态特性

    原文地址:Java中子类是否可以继承父类的static变量和方法而呈现多态特性 静态方法 通常,在一个类中定义一个方法为static,那就是说,无需本类的对象即可调用此方法,关于static方法,声明 ...

  8. 用promise和async/await分别实现红绿灯

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 贪吃蛇java版

    主要的蛇的类 import java.awt.Color; import java.awt.Graphics; import java.awt.HeadlessException; import ja ...

  10. 【托业】【新托业TOEIC新题型真题】学习笔记2-题库一-->P5-6

    P5-6 --------------------------------------单词-------------------------------------- transfrom 转化 jus ...