搜索关键字的显示处理

最后更新于:2022-04-02 04:32:38

## 搜索关键字的显示处理 ![](http://cdn.aipin100.cn/18-7-1/19254085.jpg) > 其实很多人都忽视了这个问题,不信你到一些网站上搜索 `'`、`"`、`\`试一下,看看会不会出现惊喜和意外。 页面中显示搜索词有两种方式: 1. 用js设置填充数据。 2. 直接渲染在标签中。 但这两种方式都要面临一个问题,**那就是用户输入的特殊词不能引起我们页面错误,html和JavaScript代码不能够受其影响而出错。** 如何在不限制用户输入特殊词的情况下,满足这个要求呢? 下面我们就来探讨一下这个问题。 如何解决用户搜索特殊词时,显示没有问题,搜索框中显示也没有问题,**不能引起html结构和js代码出错**。搜什么显示什么,**并且再次点击搜索按钮时,搜索的还是当前的词。** * * * * * 最简单的模糊搜索就是这样了 ```php // 不用过滤,不用进行任何处理(只是清除左右的空格符) $keyword = trim($request->param('keyword/s')); // 毕竟不用拼接sql,所以不会有任何安全问题 $where[$field] = ['like', '%' . $keyword . '%']; ``` 得益于现代ORM和PDO的完善和普及,让我们不再有拼接sql字符串的风险问题了,因为我们不需要直接拼接sql了,所以不用在进行任何过滤等处理就可以直接查询,但是用户搜索的特殊字符在页面上显示时怎么处理呢?比如搜索框中,页面上等,很多人都忽略了这个问题,但凡细心一点的人,稍加测试就能发现端倪,下面就来看一下: ```html "{:getQ(1)}"  的搜索结果 ``` ```javascript // 用js来设置搜索框的value $('.input-text').val("{:getQ(2)}"); ``` js设置时就不会出现引号和html冲突了(因为将冲突可能性转移到了js中嘛),**并且这样直接搜索时所见即所得,显示词即为搜索词。** ```php // 获取搜索词 function getQ($mode = 0) { $request = Request::instance(); $q = $request->param('q/s', ''); // 默认不做任何处理直接返回 if ($mode == 1) { // html实体转义 // html中使用 $q = htmlspecialchars($q, ENT_QUOTES); } elseif ($mode == 2) { // 单引号(')双引号(")反斜杠(\)NULL 之前添加反斜杠 // JS中使用 $q = addslashes($q); } return $q; } ``` ### 用表单插值插件处理的搜索词 ```php // 关键字搜索(后端只是去除左右多余空格符,并不会对其进行任何处理) $keyword = trim($request->param('keyword/s')); $searchDate['keyword'] = isset($_GET['keyword']) ? $_GET['keyword'] : ''; ``` ```javascript var formObj = new Form('user-form'); // json_encode() 会自动转换双引号和反斜线,以确保生成正确的json格式字符串,而这种转移和js是相通的,所以能够直接使用没有问题 var searchDate = {:json_encode($searchDate)}; formObj.init(searchDate); ``` * * * * * #### 总结 1. 我们遇到的问题是,特殊搜索词的显示(页面中显示与input搜索框中显示),和再次搜索时的搜索词不能一致的问题(我很难表述这个问题,需要你自己去感受)。 2. 我们用两种方式解决了这个问题,**html实体转义** 和 **js字符串转义** * * * * * ### 补充 你有没有遇到过,将一个页面链接通过微信发给别人,微信中却不能完整的显示地址 ``` http://www.a.com/index/index/search.html?q=地方'地方 ``` ![](http://cdn.aipin100.cn/18-6-30/32849661.jpg) 比如这个地址,有很多软件并不能够很好的识别这样的链接,对这样的链接支持得不是很友好(QQ和微信),导致你发过去后,别人不能够直接点击完整的链接,非要复制到浏览器才能打开完整的链接,这个体验就非常不好。 虽说这是个小问题,但是对于追求极致用户体验的我们来说,怎么能够忍受呢。 有什么办法解决这个问题呢。 其实浏览器向服务器发送的url都是经过url编码了: 只是浏览器地址栏经过优化,为了照顾普通用户,而显示的是这样的地址而已,我们复制就是从地址栏复制的,于是就出现这个问题了。 知道了原因后,解决方式也很简单。那就是自己降低至url编码,而不是让浏览器自己编码,你看大型网站,淘宝,京东都是这样自己编码处理的,所以地址栏你看不到搜索的中文关键字,都是被编码过了,这样就可以愉快的到处分享了。 不过貌似现代新的浏览器不会有这个问题了,看到的是中文,复制下来就是已经编码过的。但是如果你遇到了这样的问题,那解决方案就在这里。 * * * * * ### 扩展 [PHP addslashes() 函数](http://www.w3school.com.cn/php/func_string_addslashes.asp) [PHP htmlspecialchars() 函数](http://www.w3school.com.cn/php/func_string_htmlspecialchars.asp) [前端安全系列(一):如何防止XSS攻击? - 美团技术团队的个人空间 - 开源中国](https://my.oschina.net/meituantech/blog/2218539) [前端安全系列之二:如何防止CSRF攻击? - 美团技术团队的个人空间 - 开源中国](https://my.oschina.net/meituantech/blog/2243958) * * * * * last update:2018-7-1 10:34:40
';