- 前言
- 实现效果
- 实现思路
- Java编码实现
- 其他
1 前言:
注意到不少站点都有这个功能(包括javaeye和pconline)。
就是从百度/谷歌等搜索页面点过来的用户可以看见页面下方有搜索帮助提示,如图:
前一阵子给CTBA也加上了相关功能, 这里大致说说实现方法。
2 实现效果:
百度搜索”扯谈 新闻风”
点击进入CTBA的网站, 页面底部显示提示
3 实现思路:
参考了这篇文章, 利用请求的referer头. 如果乃还不知道referer是什么的话, 点这里
- 从referer头中取得来源页面的地址
- 解析出查询关键词
- 全文检索得出结果
首先必须分析referer, 知道url中哪部分是关键字。例如在baidu输入关键字"扯谈社",在搜索结果中访问你的网站,那么来源的url就是:http://www.baidu.com/s?wd=%B3%B6%CC%B8%C9%E7上面的url中,wd=%B3%B6%CC%B8%C9%E7就是关键字部分,其中%B3%B6%CC%B8%C9%E7是"扯谈社"编码后的字符串, 我们通过UrlDecode解码就可以得到原来用户输入了什么关键字访问了自己的网站, 一般的编程语言都提供了解码工具, Java里的是URLDecoder。
百度对关键字是使用GBK编码,不过有些网站比如谷歌使用的是UTF8编码,需要根据不同情况加以处理。
上面的参考文章列出各个搜索引擎的关键字,但是其实有很多已经是无效的(比如china的已经转为使用google的搜索服务),实际上还有效的列表如下(加上了后来的有道)
名称 |
关键字 |
编码 |
baidu |
wd/word |
GBK |
sogou |
query |
GBK |
yahoo |
p |
UTF-8 |
google |
q |
UTF-8 |
search.msn |
q |
UTF-8 |
youdao |
q/lq |
UTF-8 |
search.114.vnet.cn |
kw |
GBK |
4 Java的编码实现:
贴点代码
(HttpUtils.java)
/**
* 从当前请求得到请求来源
*
* @param request
* @return
*/
public static String getReferer(HttpServletRequest request) {
return request.getHeader("Referer");
}
/**
* #727 针对搜索引擎来源用户的提示
*
* 从某个url里面得到特定参数的值
*
* @param name
* @param url
* @return
*/
public static String getParameterFromUrl(String name, String url) {
if (!url.contains("?")) {
return "";
}
String reval = "";
url = url.substring(url.indexOf("?") + 1);
String[] pairs = url.split("&");
for (String pair : pairs) {
if (pair.contains("=")) {
String pairName = pair.substring(0, pair.indexOf("="));
if (name.equals(pairName)) {
reval = pair.substring(pair.indexOf("=") + 1);
return reval;
}
}
}
return reval;
}
/**
* #727 针对搜索引擎来源用户的提示
*
* 根据url取得搜索关键词
*
* @param refererURL
* request的来源url
* @return
*/
public static String getSearchKeyInRefererURL(String refererURL) {
String searchKey = "";
if (StringUtils.isNotEmpty(refererURL)) {
try {
if (refererURL.contains("baidu.com")) {
// wd/word
searchKey = getParameterFromUrl("wd", refererURL);
if (StringUtils.isEmpty(searchKey)) {
searchKey = getParameterFromUrl("word", refererURL);
}
if (StringUtils.isNotEmpty(searchKey)) {
searchKey = StringUtils.urlDecode(searchKey,
StringUtils.ENCODE_GBK);
}
} else if (refererURL.contains("sogou.com")) {
// query
searchKey = getParameterFromUrl("query", refererURL);
if (StringUtils.isNotEmpty(searchKey)) {
searchKey = StringUtils.urlDecode(searchKey,
StringUtils.ENCODE_GBK);
}
} else if (refererURL.contains("search.114.vnet.cn")) {
// kw
searchKey = getParameterFromUrl("kw", refererURL);
if (StringUtils.isNotEmpty(searchKey)) {
searchKey = StringUtils.urlDecode(searchKey,
StringUtils.ENCODE_GBK);
}
} else if (refererURL.contains("search.msn.com")
|| refererURL.contains("live.com")) {
// q
searchKey = getParameterFromUrl("q", refererURL);
if (StringUtils.isNotEmpty(searchKey)) {
searchKey = StringUtils.urlDecode(searchKey, null);
}
} else if (refererURL.contains("yahoo.com")
|| refererURL.contains("yahoo.cn")) {
// p
searchKey = getParameterFromUrl("p", refererURL);
if (StringUtils.isNotEmpty(searchKey)) {
searchKey = StringUtils.urlDecode(searchKey, null);
}
} else if (refererURL.contains("www.google")) {
// q
searchKey = getParameterFromUrl("q", refererURL);
if (StringUtils.isNotEmpty(searchKey)) {
searchKey = StringUtils.urlDecode(searchKey, null);
}
} else if (refererURL.contains("www.youdao")) {
// q or lq
searchKey = getParameterFromUrl("q", refererURL);
if (StringUtils.isEmpty(searchKey)) {
searchKey = getParameterFromUrl("lq", refererURL);
}
if (StringUtils.isNotEmpty(searchKey)) {
searchKey = StringUtils.urlDecode(searchKey, null);
}
}
} catch (Exception e) {
log.error(e.getMessage());
searchKey = "";
}
}
return searchKey;
}
(SearchEngineHintFilter.java)
在请求过滤器里面取得关键字, 进行搜索:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) {
…
String refererURL = HttpUtils.getReferer(request);
String searchKey = HttpUtils.getSearchKeyInRefererURL(refererURL);
if (StringUtils.isNotEmpty(searchKey)) {
log.debug("Got searchkey: " + searchKey+" |"+HttpUtils.getURL(httpRequest));
httpRequest.setAttribute(WebConstants.REQUEST_SEARCH_KEYWORD,
searchKey);
List<Map<String, String>> refTopics = doSearch(searchKey);
httpRequest.setAttribute(WebConstants.REQUEST_SEARCH_RESULT,
refTopics);
}
…
}
doSearch方法里面调用了庖丁分词, 根据关键字全文检索站内文章
5 其他:
提示框的CSS+JS置底 这个详情请mockee来八卦
分享到:
相关推荐
csrf绕过Referer技巧-01
如何增加Referer功能--反向链接插件
但是,它也可以用于对用户进行指纹识别。 通过该扩展名,您可以清理引荐来源标头,以使其看起来就像您刚刚通过直接在地址栏中输入地址而打开该页面一样。 特点:-每个站点的白名单选项-清理document.referer,因此...
语言:English 在每个站点上控制HTTP Referer。 Referer Control授予对...您可以全局或在每个站点上伪造所需的任何引荐来源。 或者,您可以选择完全禁用引荐来源网址。 也可以在JavaScript document.referrer上使用!
Referer-parser.cr:Snowplow的Referer-parser的Crystal实现
Referer-mod Referer Modifier是Firefox的Web扩展,用于修改HTTP请求中的Referer标头和匹配的Javascript document.referrer属性。 对于每个目标域,可以配置以下五个操作之一: 保留:请勿修改引荐来源网址 修剪:...
在瑞典语维基百科中搜索对于给定域及其子域而言404或其他方式断开的外部链接。 usage: java -jar wikipedia-referer.jar-d,--domain <arg> Domain name of links to be queried for. Will match exact domain and ...
有时,当用户来自不同来源/搜索引擎时,网站需要具有不同的行为。 在我的用例中,我们的网站必须设置一个跟踪Cookie,该跟踪Cookie对于来自Google,AOL,Yahoo或MSN的用户将具有不同的值。 我必须测试在所有情况下都...
laravel-referer, 记住原始访问者引用者 记得一个访问者引用者 在会话中记住访问者的原始引用者。 引用程序为( 优先优先级优先):utm_source 查询参数如果URL中存在外部主机,则来自请求头的Referer的域空白安装你...
$_SERVER[‘HTTP_REFERER’]是php用来判断页面上级来源页面的一个超级变局变量了,我们可以使用$_SERVER[‘HTTP_REFERER’]来判断是从哪个页面进入到此页面了,这样我们可以进行更好的跟踪了。 但是$_SERVER[...
在会话中记住访客的原始引荐来源。 引荐来源为(最高优先级优先): utm_source查询参数 如果URL中存在外部主机,则来自请求的Referer标头中的域 空的 支持我们 我们投入了大量资源来创建。 您可以通过来支持我们...
防跨站伪造测试代码,全套代码,保证实现源码
nginx模块ngx_http_referer_module通常用于阻挡来源非法的域名请求,我们应该牢记。下面这篇文章主要介绍了nginx利用referer指令实现防盗链配置的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
Referer Control授予对HTTP Referer的完全控制权。您可以全局或在每个站点上伪造所需的任何引荐来源。或者,您可以选择完全禁用引荐来源网址。也可以在JavaScript document.referrer上使用! 支持语言:English
本篇文章主要是对javascript操作referer进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助
推荐人黑名单-nginx 为 NGINX 生成一个引用黑名单
可定制的引荐来源网址 并发线程取决于您的服务器性能。 用法: webBenchmark -c [COUNT] -s [URL] -r [REFERER] -c int cocurrent thread for download (default 8) -r string referer url -s string target ...
概述ngx_txid是一个暴露$txid的模块:一个缓存的、请求范围的、20 个字符、base32hex 编码、时间和词法可排序、不... log_format referrer '$txid $http_referer'; log_format peer '$txid $remote_addr'; log_format s