zoukankan      html  css  js  c++  java
  • indy httpserver 接收URL包含中文参数乱码的问题

    在测试TIdHttpServer的时候,发现浏览器提交的URL包含中文时会乱码,我用的是XE7 UPDATE1,INDY是10。

    procedure TForm1.idhtpsrv1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);

    在这事件处理中文时,AResponseInfo好办,只要设置下

      AResponseInfo.ContentType := 'text/html';
      AResponseInfo.CharSet := 'utf-8';

    浏览器就能正确显现中文。


    对于 ARequestInfo,回头想想一开始决解方向就错了,不要想着各种编码转换,实际到这里,INDY已经把编码转换好了,因为到这里处理的文本,

     ARequestInfo.Params.Text已经是string类型了(UNICODE)。网上说是改INDY的源码,因为没地方设置TIdHTTPRequestInfo编码属性。

    改动的是IdCustomHTTPServer.pas的 TIdHTTPRequestInfo.DecodeAndSetParams(const AValue: String)方法:


    procedure TIdHTTPRequestInfo.DecodeAndSetParams(const AValue: String);
    var
      i, j : Integer;
      s: string;
      LEncoding: IIdTextEncoding;
    begin
      // Convert special characters
      // ampersand '&' separates values    {Do not Localize}
      Params.BeginUpdate;
      try
        Params.Clear;
        CharSet := 'utf-8';  //添加这一行                                                              
        // which charset to use for decoding query string parameters.  We
        // should not be using the 'Content-Type' charset for that.  For
        // 'application/x-www-form-urlencoded' forms, we should be, though...
        LEncoding := CharsetToEncoding(CharSet);
        i := 1;
        while i <= Length(AValue) do
        begin
          j := i;
          while (j <= Length(AValue)) and (AValue[j] <> '&') do {do not localize}
          begin
            Inc(j);
          end;
          s := Copy(AValue, i, j-i);
          // See RFC 1866 section 8.2.1. TP
          s := StringReplace(s, '+', ' ', [rfReplaceAll]);  {do not localize}
          Params.Add(TIdURI.URLDecode(s, LEncoding));
          i := j + 1;
        end;
      finally
        Params.EndUpdate;
      end;
    end;

    然后重新编译IndyProtocols包,注意bpl文件放在bin下,dcu和dcp文件放在Lib下的各个相应目录下(就是win32/win64, debug/release)

    测试代码:


    procedure TForm1.idhtpsrv1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);
    begin
    
      AResponseInfo.ContentType := 'text/html';
      AResponseInfo.CharSet := 'utf-8';
    
      mmo1.Lines.Add('=====================');
      mmo1.Lines.Add('Document:');
    
      mmo1.Lines.Add('');
      mmo1.Lines.Add(ARequestInfo.Params.Text);
      mmo1.Lines.Add('p1: '+ ARequestInfo.Params.Values['p1']);
      mmo1.Lines.Add('p2: '+ ARequestInfo.Params.Values['p2']);
    
      AResponseInfo.ContentText := '是中文吧'; // 'HttpServer OK';
    end;


    浏览器URL:http://127.0.0.1:8000/test?p1=中文&p2=ghg

    用 Chrome,edge,360浏览器测试正确。


  • 相关阅读:
    Python_Tips[3] -> sort/sorted 排序函数
    Python_Tips[2] -> 函数延后估值及字节码分析
    Python_Tips[1] -> 利用 Python 的字典实现 Switch 功能
    Python_Tips[0] -> 关于 import
    Python与数据库[2] -> 关系对象映射/ORM[4] -> sqlalchemy 的显式 ORM 访问方式
    Python与数据库[2] -> 关系对象映射/ORM[3] -> sqlalchemy 的声明层 ORM 访问方式
    Python与数据库[2] -> 关系对象映射/ORM[2] -> 建立声明层表对象的两种方式
    JS实现网页选取截屏 保存+打印 功能(转)
    nodejs+koa2 实现一个get请求
    windwos下安装使用nginx(转)
  • 原文地址:https://www.cnblogs.com/jankerxp/p/7774029.html
Copyright © 2011-2022 走看看