【问题标题】:strange encoding to querystring查询字符串的奇怪编码
【发布时间】:2018-09-05 01:51:27
【问题描述】:

我为演示创建了两个 aspx 页面,

page1 - WebForm1.aspx

<asp:TextBox ID="txtTest" runat="server" Width="100px"></asp:TextBox>
<asp:Button ID="btnClick" runat="server" Text="test" Width="100px" OnClick="btnClick_Click"/>

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            if (Request.QueryString["text"] == null || string.IsNullOrEmpty(Request.QueryString["text"].ToString()))
                txtTest.Text = "ö";
            else
                txtTest.Text = Request.QueryString["text"].ToString();
        }
    }

    public void btnClick_Click(object sender, EventArgs e)
    {
        HttpResponse response = HttpContext.Current.Response;
        response.Write(string.Format("<script>window.location = '{0}';</script>", HttpUtility.JavaScriptStringEncode("WebForm2.aspx?text=" + HttpUtility.UrlEncode(txtTest.Text))));
        response.End();
    }

page2 - WebForm2.aspx

<asp:TextBox ID="txtResult" runat="server" Width="200px"></asp:TextBox>
<asp:Button ID="btnBack" runat="server" Text="back" Width="50px" OnClick="btnBack_Click"/>

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            if (Request.QueryString["text"] == null || string.IsNullOrEmpty(Request.QueryString["text"].ToString()))
                txtResult.Text = "empty";
            else
                txtResult.Text = Request.QueryString["text"].ToString();
        }
    }

    public void btnBack_Click(object sender, EventArgs e)
    {
        HttpResponse response = HttpContext.Current.Response;
        response.Write(string.Format("<script>window.location = '{0}';</script>", HttpUtility.JavaScriptStringEncode("WebForm1.aspx?text=" + HttpUtility.UrlEncode(txtResult.Text))));
        response.End();
    }

然后我使用 Fiddler 跟踪网络,点击测试按钮,然后点击返回按钮。

#   Result  Protocol    Host    URL Body    Caching Content-Type    Process Comments    Custom  
6   200 HTTP    localhost:56484 /WebForm2.aspx?text=%c3%b6  835 private text/html; charset=utf-8    iexplore:12316          
8   200 HTTP    localhost:56484 /WebForm2.aspx?text=%u00f6  175 private text/html; charset=utf-8    iexplore:12316          
9   200 HTTP    localhost:56484 /WebForm1.aspx?text=%c3%b6  830 private text/html; charset=utf-8    iexplore:12316          
10  200 HTTP    localhost:56484 /WebForm1.aspx?text=%u00f6  175 private text/html; charset=utf-8    iexplore:12316          
11  200 HTTP    localhost:56484 /WebForm2.aspx?text=%c3%b6  834 private text/html; charset=utf-8    iexplore:12316  

我们可以看到 URL 正文有奇怪的编码,为什么会生成 %u00f6?可以回到 %c3%b6 吗?

当我们单击返回按钮返回第 1 页时,它的引荐来源网址丢失了。实际上我认为奇怪的编码导致了这个问题,因为当我使用 F12 开发工具更改操作(从“%u00f6”到“%c3%b6”),然后单击返回按钮时,生成了引用。

click here to see the screenshot

如果您能给出答案,非常感谢。

【问题讨论】:

    标签: c# encoding request.querystring


    【解决方案1】:

    编码行为是一个标准。根据RFC 3986

    2.4。何时编码或解码

    一般情况下,URI中的八位字节的唯一时间
    百分比编码是在从
    生成 URI 的过程中 其组成部分。这是当实现确定哪个 的保留字符将用作子组件分隔符
    并且可以安全地用作数据。一旦生成,URI 总是 以百分比编码的形式。

    取消引用 URI 时,组件和子组件
    对特定于方案的取消引用过程很重要(如果有)
    必须在百分比编码的八位字节之前解析和分离 这些组件可以安全地解码,否则数据可能会被
    被误认为是组件分隔符。唯一的例外是
    与未保留字符中的字符相对应的百分比编码八位字节
    设置,可以随时解码。例如,八位字节
    与波浪号(“~”)对应的字符通常编码为“%7E”
    通过较旧的 URI 处理实现; "%7E" 可以替换为 "~" 不改变其解释。

    因为百分号(“%”)字符用作
    的指示符 百分比编码的八位字节,它必须被百分比编码为“%25”
    八位字节用作 URI 中的数据。实施不得
    百分比编码或多次解码相同的字符串,作为解码
    已解码的字符串可能会导致对百分比的误解
    数据字节作为百分比编码的开头,反之亦然
    百分比编码已经百分比编码的字符串的情况。

    如果您想进行一些测试,也可以使用www.urlencoder.org 查看预期的 url 编码输出。

    至于为什么找不到referrer,可以看In what cases will HTTP_REFERER be empty

    最终用户时它将/可能为空

    • 在浏览器地址栏中输入了站点 URL。
    • 通过浏览器维护的书签访问了该网站。
    • 在窗口/选项卡中作为第一页访问了该站点。
    • 点击了外部应用程序中的链接。
    • 从 https URL 切换到 http URL。
    • 从 https URL 切换到不同的 https URL。
    • 已安装安全软件(防病毒/防火墙/等),可从所有请求中去除引荐来源网址。
    • 位于从所有请求中去除引荐来源网址的代理后面。
    • 以编程方式访问网站(如 curl),但未设置引荐来源标头(搜索机器人!)。

    经过一番挖掘,我从RFC 2616 看到了这个。

    14.36 推荐人

    Referer[sic] 请求头字段允许客户端指定, 为了服务器的利益,资源的地址 (URI) 获得了 Request-URI(“referrer”,虽然标头 字段拼写错误。)Referer 请求标头允许服务器 为感兴趣的资源生成反向链接列表,记录, 优化缓存等。它还允许过时或输入错误的链接到 跟踪维护。如果 Request-URI 是从没有自己的 URI 的源获得的, 例如从用户键盘输入。

    查看该段的最后一句,我相信在您的示例中您“更改”了编码。

    我使用 F12 开发工具更改操作(从 "%u00f6" 到 "%c3%b6")

    【讨论】:

    • 谢谢约翰!我正在阅读并尝试第一个答案。在我的示例中,它不在导致引荐来源网址丢失的列表中。当我在表单中手动更改操作(从“%u00f6”到“%c3%b6”),然后单击返回按钮时,引用者被返回。
    • 如果您真的对此感兴趣,可以查看Referrer Policy
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2016-12-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    相关资源
    最近更新 更多