IE9 中的 CORS Post 失败
CORS Post in IE9 fails
所以我正在创建一个应用程序,它使用 CORS 与 .NET MVC Sidecar 项目进行通信。除了在 IE9 中 POST 请求失败之外,一切都很好。我有一个允许 GET 工作的 library,但是 POST 请求仍然有问题。似乎 IE9 去掉了 contentType
header。服务器最终将其解释为 appplication/octet-stream
,而不是 text/plain
,据我所知,它实际上是由
设置的
在我的 WebAPIConfig.cs 中,我有以下函数(由 Register
调用):
private static void RegisterFormatters(HttpConfiguration config)
{
// enable browser viewing + jsonp
config.Formatters.Add(new BrowserJsonFormatter());
config.Formatters.Add(new JsonpMediaTypeFormatter(new BrowserJsonFormatter()));
// prettify json: indented + camel case
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.Formatting = Formatting.Indented;
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
// Tell the formatter to accept text/plain
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
// When we use CORS on IE9, it strips off the content type. The server assigns it application/octet-stream
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
}
但是,Fiddler 仍然告诉我请求没有 contentType,并且服务器无法处理 application/octet-stream
.
的 contentType
有人成功了吗?
根据http://caniuse.com/cors
以下浏览器支持 CORS:Firefox 3.5+、Internet Explorer 10+、Google Chrome 4.0+、Safari 4.0+、
Opera 12.0+ 和 Opera Mobile 12.0+
XDomainRequest 或许可以帮到您(IE8+)
<!DOCTYPE html>
<html>
<head>
<title>XDR</title>
<script type="text/javascript">
var xdr = new XDomainRequest();
xdr.open("get", "http://localhost:6504/api/resourcename/1");
xdr.onload=function()
{
alert(xdr.responseText);
}
xdr.send();
</script>
我最终通过创建自己的 MediaTypeFormatter
来解决这个问题,该 MediaTypeFormatter
与 application/octet-stream
一起工作。 (我的服务器不接受调用,因为我没有进行 IIS 重置 (duh),但它仍然没有正确解析对象。
这是我最终使用的格式化程序。
public class OctetStreamMediaTypeFormatter : MediaTypeFormatter
{
public OctetStreamMediaTypeFormatter()
{
// We only support octet-stream
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
var task = new Task<object>(() =>
{
using (var reader = new StreamReader(readStream, Encoding.UTF8))
{
// The data is passed as somethign identical to a query string (but not in the query string)
var dic = HttpUtility.ParseQueryString(reader.ReadToEnd());
var json = JsonConvert.SerializeObject(dic.AllKeys.ToDictionary(k =>
{
if (k.EndsWith("[]"))
{
return k.Substring(0, k.IndexOf("[]", StringComparison.OrdinalIgnoreCase));
}
else
{
return k;
}
}, k =>
{
var val = dic[k];
// We need to speciallly handle arrays
if (k.EndsWith("[]"))
{
// parse into separate values;
var values = val.Split(',');
val = values.Aggregate("[", (current, value) => current + ("'" + value + "',"));
if (val.EndsWith(","))
{
val = val.Substring(0, val.Length - 1);
}
val += "]";
}
return val;
}));
// It still puts it in as a string, which is not what we want, so we need to remove the quotes
json = json.Replace("\"[", "[").Replace("]\"", "]");
var obj = JsonConvert.DeserializeObject(json, type);
return obj;
}
});
task.Start();
return task;
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
}
所以我正在创建一个应用程序,它使用 CORS 与 .NET MVC Sidecar 项目进行通信。除了在 IE9 中 POST 请求失败之外,一切都很好。我有一个允许 GET 工作的 library,但是 POST 请求仍然有问题。似乎 IE9 去掉了 contentType
header。服务器最终将其解释为 appplication/octet-stream
,而不是 text/plain
,据我所知,它实际上是由
在我的 WebAPIConfig.cs 中,我有以下函数(由 Register
调用):
private static void RegisterFormatters(HttpConfiguration config)
{
// enable browser viewing + jsonp
config.Formatters.Add(new BrowserJsonFormatter());
config.Formatters.Add(new JsonpMediaTypeFormatter(new BrowserJsonFormatter()));
// prettify json: indented + camel case
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.Formatting = Formatting.Indented;
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
// Tell the formatter to accept text/plain
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
// When we use CORS on IE9, it strips off the content type. The server assigns it application/octet-stream
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
}
但是,Fiddler 仍然告诉我请求没有 contentType,并且服务器无法处理 application/octet-stream
.
有人成功了吗?
根据http://caniuse.com/cors 以下浏览器支持 CORS:Firefox 3.5+、Internet Explorer 10+、Google Chrome 4.0+、Safari 4.0+、 Opera 12.0+ 和 Opera Mobile 12.0+
XDomainRequest 或许可以帮到您(IE8+)
<!DOCTYPE html>
<html>
<head>
<title>XDR</title>
<script type="text/javascript">
var xdr = new XDomainRequest();
xdr.open("get", "http://localhost:6504/api/resourcename/1");
xdr.onload=function()
{
alert(xdr.responseText);
}
xdr.send();
</script>
我最终通过创建自己的 MediaTypeFormatter
来解决这个问题,该 MediaTypeFormatter
与 application/octet-stream
一起工作。 (我的服务器不接受调用,因为我没有进行 IIS 重置 (duh),但它仍然没有正确解析对象。
这是我最终使用的格式化程序。
public class OctetStreamMediaTypeFormatter : MediaTypeFormatter
{
public OctetStreamMediaTypeFormatter()
{
// We only support octet-stream
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
var task = new Task<object>(() =>
{
using (var reader = new StreamReader(readStream, Encoding.UTF8))
{
// The data is passed as somethign identical to a query string (but not in the query string)
var dic = HttpUtility.ParseQueryString(reader.ReadToEnd());
var json = JsonConvert.SerializeObject(dic.AllKeys.ToDictionary(k =>
{
if (k.EndsWith("[]"))
{
return k.Substring(0, k.IndexOf("[]", StringComparison.OrdinalIgnoreCase));
}
else
{
return k;
}
}, k =>
{
var val = dic[k];
// We need to speciallly handle arrays
if (k.EndsWith("[]"))
{
// parse into separate values;
var values = val.Split(',');
val = values.Aggregate("[", (current, value) => current + ("'" + value + "',"));
if (val.EndsWith(","))
{
val = val.Substring(0, val.Length - 1);
}
val += "]";
}
return val;
}));
// It still puts it in as a string, which is not what we want, so we need to remove the quotes
json = json.Replace("\"[", "[").Replace("]\"", "]");
var obj = JsonConvert.DeserializeObject(json, type);
return obj;
}
});
task.Start();
return task;
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
}