将base64字符串发送到c#服务器

Posted

技术标签:

【中文标题】将base64字符串发送到c#服务器【英文标题】:Sending base64 string to c# server 【发布时间】:2014-07-19 23:21:30 【问题描述】:

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

【问题讨论】:

阅读此***.com/questions/20433655/… 【参考方案1】:

出现此错误是因为您的服务器在“10.0.10.105”上侦听未在其 HTTP 响应中指定“Access-Control-Allow-Origin”标头。这是相互“对话”的网站的常见问题,您可以在here(或只是谷歌“CORS”)阅读有关它。

作为一种解决方案,让侦听该 IP 的服务器从 POST 响应中返回以下标头:

访问控制允许来源:*

这有一些您可能想了解的安全隐患(通常最好不要使用“allow-all”星号“*”,而是明确指定请求服务器)。

更新:正如“预检请求”下的那篇论文中所述,非平凡的 POST 请求要求服务器监听 OPTIONS 请求并在响应中返回这些标头:

访问控制允许来源:*

访问控制允许方法:POST、GET、OPTIONS

您能否尝试让图像服务器侦听 OPTIONS(就像您为 GET、POST 等所做的那样)并返回这些标头? (发出 'POST' 请求的客户端将自动在它之前向同一服务器发出 OPTIONS 请求,如果 OPTIONS 响应包含这些标头,则将调用后续 POST。)

【讨论】:

感谢您的回答。我已经在服务器中添加了类似的东西。 response.Headers.Add("Access-Control-Allow-Origin", "*"); response.Headers.Add("Access-Control-Allow-Origin", "10.0.10.105");但运气不好,我错过了什么吗? 请查看我的更新回复。可能需要预检请求 (OPTIONS)。 感谢您的回复,但没有运气。仍然发生错误。 您可以使用嗅探器(例如 Fiddler)并在此处复制 HTTP 流量吗?具体来说,您是否看到 OPTIONS 请求/响应?【参考方案2】:

非常感谢您的回答。它给了我很多关于访问来源的想法。看来我的问题出在配置上。我添加了这段代码,一切正常。

config.MaxReceivedMessageSize = 5000000;

当超过默认配置的最大限制大小时,程序将自动显示访问控制允许来源。

非常感谢您的想法。

【讨论】:

【参考方案3】:

所以,CORS 和 Access-Control-Allow-Origin 标头很尴尬。不久前,当我有一个 API 需要从几个不同网站上运行的 javascript 代码中引用时,我遇到了这个问题。我最终写了一个 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" ;
    

【讨论】:

非常感谢您花时间诚实地说我是 c# 中的新手,当我尝试您的代码时出现错误“名称空间 'System.Web' 中不存在类型或名称空间名称 'HttpContextWrapper' (您是否缺少程序集引用?)“如果您不介意,我必须使用什么命名空间才能使其工作?非常感谢您的帮助。 System.Web.HttpContextWrapper 存在于 .net 4.0 和 4.5 中的 System.Web.dll 中,或存在于 .net 3.5 中的 System.Web.Abstractions.dll 中。您使用的是哪个版本的 .NET?您的项目中有适当的参考吗? 非常感谢您的帮助。我试过你给定的代码。但是仍然会出现错误。不知道为什么。除了将图像转换为 base64 之外,您还有什么想法吗? 检查您的参考资料。在 .net 4.0 中,System.Web.dll 包含 HttpContextWrapper 类。确保您是 .net 4.0 版本的引用点 - 引用属性为 Version=4.0.0.0Runtime Version=v4.0.30319 是的,我已经修复了错误,并且我成功运行了您给定的代码,但在请求期间仍然发生错误。

以上是关于将base64字符串发送到c#服务器的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中从 base64 反序列化对象

在 c# 中等效于在 c 编程中生成的要在 URL 查询字符串中发送的“Base64”编码的加密字节字符串

在 C# 中将 Base64 字节数组解码为图像

C# Base64 字符串到 JPEG 图像

如何使用ajax发送大图像或其base64字符串?

使用 c# 将 FileStream 编码为 base64