首页>>技术前沿>>B/S,C/S软件系统开发
看了这篇文章,以后千万不敢乱用回车符!
作者:西安软件开发公司 | 转载 来源:西安软件开发公司 | 时间:2018年6月22日| 点击:0次 | 【评论】

 

         话说最近真是流年不利,感觉各种BUG犹如天灾一样全部冒出来了,这不昨天又解了一个非常无语的问题,大概是关于换行和正则的臭虫,下面给大家吐槽一下。

数据“野”了


         昨天同事反馈某个页面的数据没有正常显示,最开始我还以为是接口没有返回数据,结果看了下请求发现接口有正常的数据呀。没办法就一路反查回去,最后查到居然代码里接口请求抛错了?!因为定义了 Promise 的 catch 流程,所以也没有把错误抛出来。因为之前这个页面都是正常的,很久都没有改动所以我第一反应是这个数据异常了,查了半天的数据格式问题。可是问题就在于明明看到数据是正常的呀,服务端没有报错,接口数据也是可以正常解析的。最后我突然想起来,我们的接口是 JSONP 的会不会是 JSONP 功能挂了?查了一下果然是这样。

         我们都知道 JSONP 需要定义一个 callback 回调名称,最后数据加载的时候执行这个回调返回数据才算成功。可以看到图里面虽然加了 callback=? 但是并没有对 ? 进行替换,服务端那边应该也是增加了校验这种情况下并没有给我们添加回调方法名。实际上服务端这里的处理都是没问题的,因为即使 ? 被添加到数据里了也会有问题,因为 ? 是逻辑运算符并不能被定义成变量。而没有加回调方法的后果就是虽然接口返回正常,但是最终数据没有人接收就“野”了。

我的回调呢?


          我们在内部是使用了 zepto 这个基础库的。由于添加回调方法名并做替换肯定是 zepto 内部的行为,所以当我查到这的时候我都懵了。难道一年难遇一次国际知名库的 BUG 就这样被我水逆的碰到了?怀着一脸惊讶的表情我打开了 zepto 的文件继续查了下去。最终我发现还真是 zepto 里面 callback=? 没有替换成功。我看了看代码,通过正则匹配到两个 ? 后并替换最后一个 ? 为回调方法名。最开始我一直没绕过来,我在想这特么是什么骚操作?能匹配到 callback=? 么??callback=? 是可以匹配到,万一这个东西在后面 &callback=? 不就挂了么?最后才反应过来它这么做是直接匹配了整个地址后的 query,忽略了参数名称直接匹配 ?。对于这种操作,我只能说:

                                             


          那么在当前的情况下这种操作会有什么问题呢,我怀着不服输的精神又查了下去。结果我发现在这种情况下这个正则居然跪了!最后我在这打印出来看,发现传进去的 URL 里面多了一个回车符,导致这段正则失效了。因为我们知道正则里面的 . 元字符是匹配除了回车符以外的所有字符。(这无语的BUG…果然水逆就算是啥也不干问题也会自动找上门啊…


当我查到这的时候我就思考了两个问题:

          这个回车从哪里来的?参数里怎么会有回车?因为这个参数是直接从当前页的 URL 获取的,所以是我们在拼接的时候操作的有问题,还是服务端下发的当前地址就有问题?为什么到了最后 URL 地址这还有回车,正常情况下到这步的时候应该库都会对其进行转码编译了,例如回车符会被编成 %0A 这样其实 zepto 内部再处理就没有问题了呀?所以是哪里给漏编码了呢?哪里来的回车符?顺着上面两个问题,由于第一个问题的成本比较低,先看了下回车符哪里来的问题。我优先看了下当前地址,发现在当前地址的时候已经有问题了。而其他路径进入的这个页面都是正常的,只有这个特殊情况下有问题,遂反馈给服务端反查一下。最后服务端(PHP)那查到原来是因为他们读取文件时按行分割没有注意到方法里会带着换行的问题。

         大概就是服务端那会有一个 token 文件,里面按行记录着一堆 ID,服务端会使用 file() 读取这个文件,然后将每个 ID 都 map 成一个地址下发下去。使用 file() 的好处是它在读取文件的时候能自动输出一个按行分割后的数组,这样就不需要额外操作。不过服务端同学没有注意,PHP 文档里也非常清楚的写明了:

 Note:

 Each line in the resulting array will include the line ending, unless FILE_IGNORE_NEW_LINES is used,    so     you still need to use rtrim() if you do not want the line ending present.

        也就是说这种方法默认分割后的数组每个数据是包含最后的那个换行符的!想要去掉换行符需要添加 FILE_IGNORE_NEW_LINES 的标记参数。我自己也试了下发现果真如此!可以看到数组的前三个里面字符串的长度都是 4。


         最后,问题的来龙去脉前因后果总算是查清楚了。虽然这里面有各种坑,虽然服务端已经帮忙处理了,但是我明白最主要的问题还是最后的那个前段拼接的问题。所以我以血泪的历史告诉大家 URL 拼接一定要编码别搞什么骚操作啊!

此内容DOC下载 此内容PDF下载

【全文完】
关键词标签: 回车符 后台 
0 ([$-顶稿人数-$])
0 ([$-踩稿人数-$])

版权声明:

1、西安弈聪网站内容中凡注明“来源:XXX(非西安弈聪网站)”的作品,转载自其它媒体,转载目的在于传递更多信息,其中涉及的网站建设,网站优化,百度关键词优化,西安软件开发等技术细节并不代表本站赞同支持其观点,并不对其真实性负责。对于署名“西安弈聪”的作品系本站版权所有,任何人转载请署名来源,否则西安弈聪将追究其相关法律责任。

2、本站内容中未声明为“原创”的内容可能源自其它网站,但并不代表本站支持其观点,对此带来的法律纠纷及其它责任与我方无关。如果此内容侵犯了您的权益,请联系我方进行删除。