2

基本上是这样,但是我在 POST 数据中遇到了国家符号的问题。他们被破坏到服务中。

我有非常基本的标记:

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
    <form action="/hello" method="POST">
        <input name="Name" id="Name"/>
        <input type="submit" value="Send"/>
    </form>
</body>
</html>

浏览器发送以下内容:

标题:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:uk,ru;q=0.8,en;q=0.6 Cache-Control:max-age=0
Connection:keep-alive Content-Length:41
Content-Type:application/x-www-form-urlencoded
Cookie:ss-pid=s2uF57+2p07xnT9nUcpw; X-UAId= 
Host:localhost:2012
Origin:http://localhost:2012 
Referer:http://localhost:2012/Great
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36

表格数据:

Name=%D0%BF%D1%80%D0%B8%D0%B2%D1%96%D1%82

在服务中,我收到以下内容:

РїСЂРёРІС–С

而 this.Request.OriginalRequest.EncodingName 是“西里尔文(Windows)”。我认为这里应该是 UTF-8。预期结果是

привіт

PS。App.config(我正在使用 Self-Host)默认来自http://www.ienablemuch.com/2012/12/self-hosting-servicestack-serving.html

4

1 回答 1

2

我已经对此进行了研究,问题是HTTP侦听器推断出请求的字符编码Windows-1251而不是UTF-8这样做,因为请求的字符编码是在Content-TypeHTTP标头上指定的,因此它可以按预期工作如果您要将提琴手中的 Content-Type 更改为:

Content-Type: application/x-www-form-urlencoded; charset=utf-8

不幸的是,HTML 表单不允许您使用如下所示的字符集指定 Content-Type:

<form action="/hello" method="POST" 
      enctype="application/x-www-form-urlencoded; charset=utf-8">
    <input name="Name" id="Name"/>
    <input type="submit" value="Send"/>
</form>

但是浏览器实际上忽略了这一点,而是发送默认的 Form Content-Type,例如:

Content-Type: application/x-www-form-urlencoded

在这种情况下,由于缺少 Content-Type,HTTP 侦听器会尝试从 POST 数据中推断 Content-Type:

Name=%D0%BF%D1%80%D0%B8%D0%B2%D1%96%D1%82

它推断为Windows-1251并使用该编码解析值。

有几个解决方案,第一个是覆盖刚刚在此提交中启用的内容编码并强制使用 UTF-8 编码,例如:

public override ListenerRequest CreateRequest(HttpListenerContext httpContext, 
    string operationName)
{
    var req = new ListenerRequest(httpContext, 
        operationName, 
        RequestAttributes.None)
    {
        ContentEncoding = Encoding.UTF8
    };
    //Important: Set ContentEncoding before parsing attrs as it parses FORM Body
    req.RequestAttributes = req.GetAttributes(); 
    return req;
}

此功能将在 v4.0.19 版本中,现在可在 MyGet 上使用

第二种解决方案是有效地为 HTTP 请求提供提示,以推断请求UTF-8,您可以通过指定英文的第一个字段来执行此操作,例如:

<form action="/hello" method="POST">
    <input type="hidden" name="force" value="UTF-8"/>
    <input name="Name" id="Name"/>
    <input type="submit" value="Send"/>
</form>

force=UTF-8除了它的英文和使用 ASCII 字符集之外,没有什么特别的。

于 2014-04-30T06:46:07.280 回答