查询字符串的奇怪编码

时间:2018-09-05 01:51:27

标签: c# encoding request.querystring

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

第1页-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

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

1 个答案:

答案 0 :(得分:0)

编码行为是一种标准。按照RFC 3986

2.4。何时进行编码或解码

  

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

     

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

     

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

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

关于引荐来源失踪的原因,您可以看看In what cases will HTTP_REFERER be empty

  

当最终用户使用时,它将为空

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

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

14.36推荐人

  

Referer [sic]请求标头字段允许客户端指定,   为了服务器的利益,从中获取资源的地址(URI)   获得了Request-URI(“引荐来源网址”,尽管标头   字段拼写错误。)Referer请求标头允许服务器执行以下操作:   生成指向资源的反向链接列表,以进行关注,记录,   优化的缓存等。它还允许过时或输入错误的链接   跟踪维护。如果以下情况,则不得发送Referer字段:   请求URI是从没有自己的URI的来源获得的,   例如来自用户键盘的输入。

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

  

我使用F12 Developer工具将操作(从“%u00f6”更改为   “%c3%b6”)