问题背景:
注:下文中 ”webapi“ 和 “webapi” 和“webapi 2”的概念是不一样的,共有3个概念。
前者指asp.net平台中的一种项目框架,
第二个webapi指的其实是“webapi 1”,即.NET 4.0下的webapi框架,
webapi 2指的其实是“webapi 2”,即.NET 4.5+下的webapi框架。
现在我用的(准确来说是我司用的)是.NET 4.0平台,也就是说只能用“webapi 1”而不能用“webapi 2”(不要问我为什么),这样的话就有了新的问题。
既然用到webapi项目,那么跨域显然是难以避免的了,比如 aaa.test.com 向 webapi.test.com发请求,然后得到返回信息。
这就是跨域。
跨域的解决方案也很明显了,每个web开发者都跑不掉的。
1. 同源策略配置解决
2. jsonp方案。
------------------------------
以下是答案。
同源策略方案:
同源策略的配置就是在webapi.test.com站点的web.config文件中配置如下内容 <system.webServer>节点中:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Expose-Headers" value="key" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
然后跨域请求就可以成功了。
但是问题也有,就是兼容性差。老版IE好像都不行,IE678.
jsonp方案:
问题是webapi(此处指webapi1,webapi 2中怎样,暂未具体了解)中,没有返回jsonp的形式。
如果需要返回jsonp,则需要我们对webapi的http请求的返回信息进行扩展。
搜索webapi jsonp,能搜到很多东西。
这里面详细讲了如何扩展webapi使之能够返回jsonp形式的内容。
但是使用webapi的我们,直接将代码复制过来,却是报错的 。
因为.NET 4.0中是不支持这种写法的。
如图中红框处。
其他地方都一切正常。
因此,我们不得不对此处进行改写,其实也就是一个异步的写法而已。
C#的异步写法经过了几次进化,新的写法不支持,那么旧的写法总是可以的。因此这个问题是肯定可以解决的。
改写如下:
代码如下:
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
{
return Task.Factory.StartNew(() =>
{
this.WriteToStream(type, value, writeStream, content);
});
}
catch (Exception exception)
{
TaskCompletionSource<AsyncVoid> source = new TaskCompletionSource<AsyncVoid>();
source.SetException(exception);
return source.Task;
}
}
其余一切照常,据初步测试来看,好像没有什么问题。
当然别忘了$.ajax()的参数中加入 dataType: "jsonp", 。