今天终于解决了xss这个潜在的问题,编辑器使用的是Markdown编辑器EpicEditor,EpicEditor是一款Markdown编辑器,或者说是一款可以自己定制的编辑器。后台Markdown解析器用的是"github.com/russross/blackfriday",后台代码
func Markdown2HTML(content string) string {
content = html.EscapeString(content)
output := blackfriday.MarkdownCommon([]byte(content))
return string(output)
}
直接将markdown语法的串解析为html语法的串,后台还设置了一个markdown解析api后面待用,api的controller代码如下
// parse markdown
type MarkdownController struct {
controllers.BaseController
}
func (this *MarkdownController) Get() {
this.Data["json"] = map[string]interface{}{
"result": false,
"msg": "only post method support",
"refer": nil,
}
this.ServeJson()
}
func (this *MarkdownController) Post() {
content := this.GetString("content")
log.Blueln(content)
rst := utils.Markdown2HTML(content)
this.Data["json"] = map[string]interface{}{
"result": true,
"msg": "success",
"preview": rst,
"refer": nil,
}
this.ServeJson()
}
前端将串传给后端,这个串期望是纯markdown的,因此如果其中夹杂着有html语法,html将会被转义,之后返回带有解析后的html串。
前端的EpicEditor默认是能够解析Markdown和兼容HTML的,甚至不过滤js(这个问题我已经向项目作者反馈过,他决定之后会给其添加选项以禁用js),由于我之前的文章提到css都会给用户机会造成页面混乱,而我所找到的过滤器只支持xss过滤,即只过滤js不过滤css,并且那个过滤器有一个依赖包在墙外,这将会是很蛋疼,所以决定使用markdown,是纯markdown。EpicEditor是兼容html的,因此不满足我的需求,于是我问EpicEditor的作者是否有禁用html的选项(传送),他告诉我EpicEditor不负责解析的,解析器可以自己定制,EpicEditor默认使用的解析器是markd解析器,然后给了我一个页面,其上有定制解析器的demo
var editor = new EpicEditor({
parser: function (str) {
var blacklist = ['foo', 'bar', 'baz'];
return str.split(' ').map(function (word) {
// If the word exists, replace with asterisks
if (blacklist.indexOf(word) > -1) {
return '****'
}
return word;
}).join(' ');
}
}).load();
自己重做一个解析器?看一下markd项目的代码有多少吧,重做工作量太大。仔细分析上面的代码发现parser是一个函数,它的作用是这样的,传入原串,返回解析后的串。这回我之前留的api起作用了,自己实现的parser函数如下
parser: function (str) {
var rst = $.ajax({
async: false,
type: "post",
url: "/api/markdown/preview",
data: {"content": str},
dataType:"json",
}).responseText;
var json = eval('('+rst+')')
console.log(json);
return json.preview;
},
是的,我将原数据传给服务器去解析,得到结果,这样还有一个好处就是保证了解析器的一致性,即最终结果与编辑器preview结果是一致的。当然这也是有一些缺点的,那就是给服务器增加了负担,不过我觉得这是值得的。最后附上编辑器工作的截图
问题能够得以解决应当感谢各个开源项目以及其作者的无私奉献,还有他们的热心答疑,取之于开源用之于开源,Goj也会是一个开源项目,愿早日完成。