Wget下载含中文字符的资源的出现乱码现象的分析和处理

来源:互联网 发布:现货数据接口 编辑:程序博客网 时间:2024/06/05 21:09

--restrict-file-names=OS  限定文件名中的字符为 OS 允许的字符。--restrict-file-names=OS  restrict chars in file names to ones OS allows.

在路由器上做离线下载时,移植了wget,发现乱码现象,现记录如下。


1 现象

1.1 ftp_server.exe工具(或windowns XP IIS 中的FTP服务器)





wget自动将中文转为URL编码,下载不成功。

1.2 WingFTP工具




wget自动将中文转为URL编码,下载成功。

2 分析和处理

每个操作系统有自己的编码,中文的windows系统默认编码为GBK。每个应用程序也有自己的编码,它可以直接采用操作系统默认的编码,也可以设置为其它的编码。
wget下载时,编码转换过程wget(浏览器)->任何特殊的字符(就是那些不是简单的七位ASCII,如汉字)进行URL编码->unicode编码(服务器)->浏览器设定的编码。1)浏览器设定的编码为unicode,则结果是一串由"%"、数字和字母组成的字符串。2)如果浏览器不是unicode编码,则将unicode编码转换为浏览器端的编码格式,这时就可能产生乱码。

从上面的图片中可以看出,wget在下载时,先自动将中文字符转为URL编码,然后再进行下载。ftp_server 是不支持url编码解码的,也就是ftp_server回应wget对含有url编码资源的请求时,会回复没有这个资源。Windows XP的IIS也存在同样的问题。而wingFTP是可以支持URL编码解码的,所以wget下载wingFTP上的含有中文字符资源时,是可以将该资源下载下来的。但中文乱码还没有完全解决:用wget下载时,若文件名含有非ASCII字符或其他特殊字符,就会出现所谓的乱码。即下载下来的资源的名字包含乱码。如下图:


下面说说两种解决的方法:
  • 加入 --restrict-file-names=nocontrol 命令参数
该参数的说明如下

--restrict-file-names=OS  限定文件名中的字符为 OS 允许的字符。--restrict-file-names=OS  restrict chars in file names to ones OS allows.


  • 修改url.c
对URL字符串进行编码的源代码文件是url.c。其中,url_file_name()的功能是根据URL判断应该以什么文件名保存文件。而该函数又调用了append_uri_pathel(),该函数调用了FILE_CHAR_TEST()宏,它用于判断URL中的字符是不是特殊字符(也就是需要进行URL编码的字符。当然,包括中文)。问题就出在这个宏身上了。为了不对中文转义,需要将中文字符当作普通字符对待。将如下所示的 FILE_CHAR_TEST()宏:
#define FILE_CHAR_TEST(c, mask) \    ((opt.restrict_files_nonascii && !c_isascii ((unsigned char)(c))) || \    (filechr_table[(unsigned char)(c)] & (mask)))
修改为:
#define FILE_CHAR_TEST(c, mask) \(((opt.restrict_files_nonascii && !c_isascii ((unsigned char)(c))) || \(filechr_table[(unsigned char)(c)] & (mask))) \&& !((c|0x0fffffff) == 0xffffffff)) /* 排除中文 */
这个做法在wget 1.12中没有作用,其他版本没有尝试过。但如果拿掉FILE_CHAR_TEST()( if (!FILE_CHAR_TEST (*p, mask)) )的判断是可以的,这样就不出现乱码,但却违背了URL编码的初衷——安全。
说明:wget版本为1.12。
0 0