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

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

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

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

ssserver 启动报错:

ssserver -c /etc/shadowsocks.json  -d start
INFO: loading config from /etc/shadowsocks.json
/usr/lib/python2.6/site-packages/shadowsocks/shell.py:155: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
  e.message)
ERROR: found an error in config.json: No JSON object could be decoded

从来没见过的问题- –

于是放狗搜,先是搜到了这个 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 真是太难用了,当初我是怎么用的下去的。

 

 


本文链接:https://www.starduster.me/2015/06/02/shadowsocks-valueerror/
本站基于 Creactive Commons BY-NC-SA 4.0 License 允许并欢迎您在注明来源和非商业使用前提下自由地对本文进行复制、分享或基于本文进行创作。
请注意:受限于笔者水平,本站内容可能存在主观臆断或事实错误,文中信息也可能因时间推移而不再准确,在此提醒读者结合自身判断谨慎地采纳。

8 条评论


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

    回复

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

      回复

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

    回复

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

        回复

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

          回复

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

发表回复

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

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据