搜索关键字的显示处理
最后更新于: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
';