解决thinkjs开发jsonp接口返回Unicode时的问题
前言
第一次使用thinkjs写后端,踩了不少坑,其中有一个坑想了很久,无奈网上关于thinkjs的教程还是偏少,问了不少人,耗时很久,所以在这里mark下。
问题
需求很简单,后端返回通过接口把数据返回给前端,因为考虑到跨域问题,接口选择采用jsonp
形式。其实就是平台平时提供给我们的那些接口,想想自己也能写接口,还是很激动的!类似下面的接口:
然后前端通过ajax请求接口,搞定!thingjs的controller本身就提供各种数据格式返回的封装。
比如,你要返回json格式,直接在controller里使用
async byrefererAction(self){
let data = {
success: false,
msg: "非法请求来源"
};
return this.json(data);
}
如果要返回jsonp格式:
return this.jsonp(data);
很方便。调试一看,还是没完,和我们平时看到的平台接口还是有点不一样,为了解决低级浏览器乱码问题,人家返回的中文时Unicode编码的:
所以我还要做一步转码工作,找了一遍,发现nodejs没有现成的转Unicode方法,通过大家自己写的一个小函数实现:
let toUnicode = (s)=>{
if(s == '' || typeof s !== 'string') return s;
s = s.replace(/[\u00FF-\uFFFF]/g,function($0){
return '\\u'+$0.charCodeAt().toString(16);
});
return s;
}
所以加入转码后接口代码变成这样:
async byrefererAction(self){
let toUnicode = (s)=>{
if(s == '' || typeof s !== 'string') return s;
s = s.replace(/[\u00FF-\uFFFF]/g,function($0){
return '\\u'+$0.charCodeAt().toString(16);
});
return s;
}
let data = {
success: false,
msg: toUnicode("非法请求来源")
};
return this.jsonp(data);
}
一切看似很完美,但是结果却是这样的:
可以发现,接口返回在浏览器请求debug的response下看到的是\\u
开头的,在preview下看到是\u
开头的,然后通过js赋值到页面显示结果也还是\u
的Unicode,而不是中文。所以结果是不对的,对比平台提供的接口,正常情况下,应该是response下看到的是\u
开头的,然后在preview下看到的是中文才对了。
一度以为是转Unicode出了问题,比如说转的时候return '\u'+$0.charCodeAt().toString(16);
直接用\u替换不就行了么?事实是不行的,这里用两个斜杠是因为第一个是转义用的,否则会直接编译错。
后来加入到thinkjs的群,在里面提问,其中有人提到了是jsonp的原因,因为jsonp里面会进行再次转义。
也就是说我拿到的data是转Unicode后的,然后再通过thinkjs提供的this.jsonp(data)
或者this.json(data)
后,就进行了再一次转义,导致接口返回的是\\u
开头的。
如果真的是这个问题,那我可以自己组装jsonp格式返回,不使用thinkjs提供的吗?因为所谓jsonp,只是多了个callback。
所以往这个思路做了尝试:
async byrefererAction(self){
let toUnicode = (s)=>{
if(s == '' || typeof s !== 'string') return s;
s = s.replace(/[\u00FF-\uFFFF]/g,function($0){
return '\\u'+$0.charCodeAt().toString(16);
});
return s;
}
let data = {
success: false,
msg: "非法请求来源"
};
data = JSON.stringify(data);
data = toUnicode(data);
return this.end(`${this.param('callback')}(${data})`);
}
果然,得到的结果终于是正确的了:
终于可以睡着了(~﹃~)~zZ
手机阅读请扫描下方二维码:
原来一切都是jsonp的锅,以前都是直接utf-8编码返回中文,没有这个烦恼
0KeeTeam
0KeeTeam
12345678

12345678

12345678

12345678

12345678

0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
aytorjrjlwpvdugzpfkl
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
CRLF-Header:CRLF-Value
0KeeTeam%0d%0aCRLF-Header:CRLF-Value
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam'and/**/extractvalue(1,concat(char(126),md5(1278359945)))and'
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
0KeeTeam
expr 898338261 + 841328709
0KeeTeam|expr 922628588 + 840187536
0KeeTeam
0KeeTeam'//and(select'1'from//pg_sleep(0))>'0
0KeeTeam'//and(select'1'from//pg_sleep(2))>'0
0KeeTeam'and(select+1)>0waitfor/**/delay'0:0:0
0KeeTeam'and(select+1)>0waitfor/**/delay'0:0:2
0KeeTeam'//and//DBMS_PIPE.RECEIVE_MESSAGE('i',0)='i
0KeeTeam'//and//DBMS_PIPE.RECEIVE_MESSAGE('y',2)='y
0KeeTeam
0KeeTeam
Crawlergo
Crawlergo
Crawlergo
Crawlergo
CRLF-Header:CRLF-Value
Crawlergo
hilaknzpcpocgxuahmtu
Crawlergo%0d%0aCRLF-Header:CRLF-Value
Crawlergo\r\nCRLF-Header:CRLF-Value