我现在做了一个c#web api。它工作正常,直到今天。 我试图将图像转换为base64string,然后通过ajax将base64string发送到c#服务器。当我执行上述步骤时,会发生错误。
XMLHttpRequest cannot load http://10.0.10.105:50231/api/hello. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://10.0.10.201' is therefore not allowed access.
我不知道主要问题存在于哪里但在我的观察中,只有在将非常长的base64string传递给服务器时才会出现错误,因为当我尝试发送短测试字符串时问题不会出现并且一切正常。
您是否知道解决此问题的更好方法是什么?或者以任何其他方式实现我所需的目标?我的ajax代码是这样的。
$.ajax({
type: 'POST', //GET or POST or PUT or DELETE verb
url: 'http://10.0.10.105:50231/api/hello', // Location of the service
contentType: 'application/x-www-form-urlencoded', // content type sent to server
data: { action: "3",pers_guid:"wew",base64image:"this-is-the-base64-image"},
//dataType: 'jsonp', //Expected data format from server
//processdata: true, //True or False
success: function (data) {//On Successfull service call
$scope.pageView = 2;
console.log("THE Data description for match : " + data[0].description);
},
error: function (msg) {// When Service call fails
alert(msg);
}
});
和我的c#服务器类似(这不是整个代码)。
public class theHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
return base.SendAsync(request, cancellationToken)
.ContinueWith((task) =>
{
HttpResponseMessage response = task.Result;
response.Headers.Add("Access-Control-Allow-Origin", "*");
return response;
});
}
}
public class HelloController : ApiController
{
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
//.... more code here
}
当我尝试传递一个很长的字符串时,这是结果......
Request URL:http://10.0.10.105:50231/api/hello
Request Headers CAUTION: Provisional headers are shown.
Accept:*/*
Content-Type:application/x-www-form-urlencoded
Origin:http://10.0.10.201
Referer:http://10.0.10.201/kiosk/
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
Form Dataview sourceview URL encoded
action:3
pers_guid:wew
base64image:the_long_base64_string
但是当我传递一个示例字符串时,这就是结果。
Remote Address:10.0.10.105:50231
Request URL:http://10.0.10.105:50231/api/hello
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:49
Content-Type:application/x-www-form-urlencoded
Host:10.0.10.105:50231
Origin:http://10.0.10.201
Referer:http://10.0.10.201/kiosk/
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
Form Dataview sourceview URL encoded
action:3
pers_guid:wew
base64image:sample_string
Response Headersview source
Access-Control-Allow-Origin:*
Content-Length:103
Content-Type:application/json; charset=utf-8
Date:Wed, 04 Jun 2014 01:02:35 GMT
Server:Microsoft-HTTPAPI/2.0
答案 0 :(得分:1)
此错误显示是因为您的服务器侦听'10 .0.10.105'未在其HTTP响应中指定“Access-Control-Allow-Origin”标头。对于相互“交谈”的网站而言,这是一个常见问题,您可以阅读here(或只是Google“CORS”)。
作为解决方案,让服务器侦听该IP从POST响应中返回以下标头:
Access-Control-Allow-Origin:*
这有一些您可能想要阅读的安全隐患(通常最好不要使用“allow-all”star'*',而是明确指定请求服务器)。
更新:如“预检请求”中的那篇论文所述,非平凡的POST请求要求服务器也监听OPTIONS请求并在响应中返回这些标头:
Access-Control-Allow-Origin:*
Access-Control-Allow-Methods:POST,GET,OPTIONS
你能尝试让图像服务器监听OPTIONS(就像你为GET,POST等做的那样)并返回这些标题吗? (发出'POST'请求的客户端将自动在它之前向同一服务器发出OPTIONS请求,如果OPTIONS响应包含这些头,则将调用后续的POST。)
答案 1 :(得分:1)
非常感谢您的回答。它给了我很多关于访问起源的想法。似乎我的问题在于配置。我添加了这段代码,一切正常。
config.MaxReceivedMessageSize = 5000000;
当程序超过默认配置的最大限制大小时,程序将自动显示access-control-allow-origin。
非常感谢您的想法。
答案 2 :(得分:0)
因此,CORS和Access-Control-Allow-Origin
标题很笨拙。当我有一个需要从几个不同网站上运行的JavaScript代码引用的API时,我偶然遇到了这个。我最后写了一个ActionFilterAttribute
来为我的API控制器处理它:
[AttributeUsage(AttributeTargets.Method)]
public class AllowReferrerAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
var ctx = (System.Web.HttpContextWrapper)actionContext.Request.Properties["MS_HttpContext"];
var referrer = ctx.Request.UrlReferrer;
if (referrer != null)
{
string refhost = referrer.Host;
string thishost = ctx.Request.Url.Host;
if (refhost != thishost)
ctx.Response.AddHeader("Access-Control-Allow-Origin", string.Format("{0}://{1}", referrer.Scheme, referrer.Authority));
}
base.OnActionExecuting(actionContext);
}
}
您可以使用该属性修饰控制器的方法,并为调用者的网站添加正确的Access-Control-Allow-Origin
,无论该网站是什么。假设您使用IIS作为主机...将不适用于OWIN托管的站点。
使用示例:
public class HelloController : ApiController
{
[AllowReferrer]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}