shadowsocks 启动时报错 ValueError : No JSON object could be decoded 问题

最近一直沉迷于军国主义黄赌毒游戏和折chao腾xie各种实验报告并没有怎么沉下心来研究过技术方面的问题,正好今天遇到一个神奇的问题(其实不是自己遇到的是别人遇到的),就此记录。

机器是:Vultr 低配VPS,CentOS 6 x64

参考教程是 https://php-rmcr7.rhcloud.com/shadowsocks-server/  (写的挺详细的,这种教程真是对小白再怎么详细也不为过)

ssserver 启动报错:

从来没见过的问题- –

于是放狗搜,先是搜到了这个 https://www.v2ex.com/t/153109 ,原帖作者说道:

谢谢各位的指点,谢谢了,祝大家周末愉快,
已经解决,出错的原因蛋都碎了,原来每一行前面应该有空格,加一个tab键就好了,

我的表情是这样的:

1f178a82b9014a90a12bde0ea9773912b31bee68

虽然这原因比较扯淡但是类似的神奇问题并不是没遇到过,于是尝试重现问题,在 ssh 里直接删除了配置文件前面的 TAB,未果(我也没抱多大希望),ssserver 依旧是很欢脱地跑了起来。

继续搜,于是看到了这个 http://www.crifan.com/fixed_problem_for_python_valueerror_no_json_object_could_be_decoded/

Python中的Json库去解析对应的字符串的时候,即使是你保证了json字符串(或文件)是UTF-8,那么也未必就可以正确解码的,因为如果是在Windows下,那么默认是带BOM的UTF-8,此时Json库也是无法识别对应字符串的。

只有确保为无BOM的Json字符串,Python中的Json库,才可以正确解析的。

Windows 和 Unix 系编码问题引起的无数神奇问题我也算是有所耳闻,还有万恶的换行符引起的读取问题。

于是尝试重现问题。

使用 PuTTY 连接,vim 编辑/etc/shadowsocks.json ,ssserver 还是很欢脱的跑了起来。

记事本打开一个空文件,编辑,scp 传上去,ssserver 还是毫无问题的跑了起来。

没有办法,在 Windows 下编辑了一个文本,用 notepad++指定选择带 BOM 的 UTF,scp 传上去,终于出现了这个错误。

ssjsonerror(实在是艰难- – 真不知道那家伙怎么折腾出来的,大概是直接复制网页的时候复制到了什么奇怪的字符?)

把配置文件删了重建立一个就能解决这神奇的问题(但是这家伙直接重装了系统)


 

于是顺便就查了一下关于这个 BOM 的知识。

UTF-8是UNICODE的一种变长度的编码表达方式,UTF-8就是以8位为单元对UCS进行编码,而UTF-8不使用大尾序和小尾序的形式,每个使用UTF-8存储的字符,除了第一个字节外,其余字节的头两个比特都是以”10″开始,使文字处理器能够较快地找出每个字符的开始位置。为了与以前的ASCII码兼容(ASCII为一个字节),UTF-8选择了使用可变长度字节来存储Unicode

关于 UTF-8的特性中提到:

字节0xFE和0xFF在UTF-8编码中从未用到,同时,UTF-8以字节为编码单元,它的字节顺序在所有系统中都是一様的,没有字节序的问题,也因此它实际上并不需要BOM

什么是 BOM?

字节顺序标记英语:byte-order mark,BOM)是位于码点 U+FEFF的统一码字符的名称。当以UTF-16或UTF-32来将UCS/统一码字符所组成的字符串编码时,这个字符被用来标示其字节序。它常被用来当做标示文件是以UTF-8、UTF-16或UTF-32编码的记号。

字符U+FEFF如果出现在字节流的开头,则用来标识该字节流的字节序,是高位在前还是低位在前。如果它出现在字节流的中间,则表达零宽度非换行空格的意义,用户看起来就是一个空格。从Unicode3.2开始, U+FEFF只能出现在字节流的开头,只能用于标识字节序,就如它的名称——字节序标记——所表示的一样;除此以外的用法已被舍弃。取而代之的是,使用 U+2060来表达零宽度无断空白。

关于 BOM 在 Windows 和 Unix 之间的那些问题:

UTF-8则没有字节顺序的议题。UTF-8编码过的字节顺序标记则被用来标示它是UTF-8的文件。它只用来标示一个UTF-8的文件,而不用来说明字节顺序。许多Windows程序(包含记事本)会添加字节顺序标记到UTF-8文件。然而,在类Unix系统(大量使用文本文件,用于文件格式,用于进程间通信)中,这种作法则不被建议采用。因为它会妨碍到如解译器脚本开头的Shebang等的一些重要的码的正确处理。它亦会影响到无法识别它的编程语言。如gcc会报告源码文件开头有无法识别的字符。而在PHP中,如果没有激活输出缓冲(output buffering),它会使得页面内容开始被送往浏览器(即:用户头文件已被提交),这使PHP脚本无法指定用户头文件(HTTP Header)。字节顺序标记在UTF-8中被表示为序列 EF BB BF,对大部分未准备好处理UTF-8的文本编辑器及网页浏览器而言,在ISO-8859-1的环境中则会显示 。对于已于IANA注册的字符集UTF-16BE、UTF-16LE、UTF-32BE和UTF-32LE等来说,不可使用字节顺序标记。

参考资料 维基百科:UTF-8 和 维基百科:字节顺序标记

——PS。最近天气不好,中文维基并不能正常打开,请自备梯子或者使用临时的在线代理比如这个

总之一句话就是在 Windows 下对 Linux 服务器进行操作务必注意编码问题,必要时常备 npp 这种强大的编辑器,解决编码问题方便一些。还有就是习惯了原生终端之后 PuTTY 真是太难用了,当初我是怎么用的下去的。

 

 

7条评论


  1. 我是在配置VPS(虚拟专用服务器)的时候遇到的这个问题,我在windows环境下,通过网页终端来访问的服务器,在不能复制、粘贴的情况下,我手打了这些代码,然后现在编码格式不对了?有点崩溃啊。

    回复

    1. 我是因为把一个冒号打成了两个。

      回复

  2. 来打个卡,问题解决。。世界真小啊-by 碳酰氯

    回复

      1. 你好我也遇到了这个问题,不会解决了,没看懂你的解决方法,不知道该怎么弄。能给解答下么??

        回复

        1. 简单的说就是在服务端完全新建一个配置文件手打不要复制。。。

          回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.