将base64字符串发送到c#server

时间:2014-05-30 08:50:17

标签: c# javascript ajax cors

我现在做了一个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

3 个答案:

答案 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" };
    }
}