做内容站的都想让老用户少走一步:地址栏里敲出域名,按一下 Tab,接着输关键词就能搜站内的帖子。Chromium 把这个叫 Tab to Search,Firefox、Safari、Edge 也都支持,背后共用的是 OpenSearch 描述文件这套约定。文件本身不难写,麻烦在写完以后浏览器肯不肯把它亮出来。
描述文件长什么样
十七度自己就挂了一份,拿来当例子正好:
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>十七度 Search</ShortName>
<Description>Search for posts on 十七度</Description>
<Url type="application/opensearchdescription+xml" rel="self"
template="https://www.shiqidu.com/opensearch.xml"/>
<Url type="text/html" template="https://www.shiqidu.com/search?q={searchTerms}"/>
</OpenSearchDescription>
(原文件还有 Tags、Image、Query 几行,这里删掉了。)
按 OpenSearch 1.1 草案第 6 版,ShortName 是必填项,只许写一次,限 16 个字符以内的纯文本。Description 放得宽些,上限 1024 个字符。Url 的 template 里写 {searchTerms} 占位,浏览器会把用户输入的词替换进去。带 rel="self" 的那条 Url 指回文件自己,MDN 说这样描述文件可以自动更新。
MDN 的《OpenSearch description format》列了几个容易出错的地方:
- 根元素要带 xmlns,漏了的话 Firefox 可能提示下载不了搜索插件。
- 至少要有一个
text/html类型的 Url,只给 Atom 或 RSS 的话 Firefox 不认。 - template 里的
&要转义成&。 - 服务端返回的 Content-Type 应当是
application/opensearchdescription+xml。 - 远程加载的图标别超过 10 KB,Firefox 会拒收。MDN 建议尽量同时给一个 16×16 的
image/x-icon和一个 64×64 的 PNG 或 JPEG。
十七度这份文件的响应头给的是 application/xml,没用规范注册的那个类型。各家浏览器对此宽不宽容,要装一遍才知道。
在 head 里声明
<link rel="search" type="application/opensearchdescription+xml"
title="十七度 Search" href="https://www.shiqidu.com/opensearch.xml">
规范里 title 只是可选项,MDN 则要求它跟描述文件的 ShortName 一致,照后者写更稳。Chromium 的 Tab to Search 说明还提到,它只登记用户直接访问根地址、没带路径的那些站,所以这个 link 起码得放进首页。
一个页面也可以挂多条 link,像一份按作者、一份按标题,title 分开写就行。
没写描述文件的站,Chromium 还有一条退路:用户在站内提交过搜索表单,它也可能自动登记。条件比较苛刻:表单得是 GET,结果走 HTTP 地址,没有 onsubmit 脚本。表单里只许一个文本输入框,密码、文件上传和 textarea 都不能有,其余元素也得保持默认状态。站内搜索如果是前端拦截后发异步请求,就对不上这些条件,老老实实写描述文件省心。
联想词
想在输入过程中就出候选,再加一条 Url:
<Url type="application/x-suggestions+json"
template="https://example.com/suggest?q={searchTerms}"/>
按 Suggestions 扩展草案,接口返回一个 JSON 数组:头一个元素回显用户输入的前缀,接着是候选词列表,这两样必填。后面的描述和跳转 URL 可以不给。MDN 提到 Firefox 63 起也接受 application/json 作为这个类型的别名,Chromium 那页的写法是把 type 设成同一个值,再加 rel="suggestions"。两边写法有出入,按目标浏览器各测一遍。
声明了也不一定露面
MDN 写得很明白,浏览器怎么展示各不相同,Chrome 默认把网站搜索登记为未激活。对照 Chrome 帮助中心,这类站点会出现在 Inactive shortcuts 里,有的要在站内搜过一次才会列进去,用户还得手动点 Activate。Firefox 的提示是搜索框图标的变化,界面上没显示那个框的话,用户什么也看不到。
你们站的联想接口做了缓存吗,还是每敲一个字都打到数据库?