重定向
重定向的分为两种301和302, 这两种使用起来感觉差不多, 但是对搜索引擎来说是有区别的
301 表示永久重定向, 搜索引擎收到301响应时会把旧的地址的权值传给新的, 所以当网站更改域名或者网站内部资源url改变时应该使用301重定向
302 表示临时重定向, 顾名思义就是告诉搜索引擎, 这个新地址只是临时用一用
权值分散
当一个网站有多个域名的时候, 据个人经验, 应当把所以域名都重定向到一个主域名上, 例如abc.com、www.abc.com、home.abc.com, 这三个都指向一个网站, 会造成权值的分散
更坏的情况是别人把他的域名定到你的网站上, 让你的网站来养着他的域名, 等时机成熟, 别人把域名一收, 你的网站就突然流失了一大部分流量
所以最好就是在代码中(或者在容器中)对域名进行重定向, 检测请求中的域名, 若不是主域名如www.abc.com就全部301重定向过来
springboot中的实现
完整代码
HostInterceptor.java
编写一个通用的拦截器, 首先检测请求方式, 只对get请求进行重定向, 因为get请求来自浏览器, 会自动对301重定向进行页面跟随。 之后检查域名若不在白名单中则进行重定向
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| public class HostInterceptor implements HandlerInterceptor {
private String redirectHost; private Integer redirectPort; private Set<String> hostWhitelistSet = new TreeSet<>();
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) {
if (redirectHost == null) { return true; }
if (!"get".equals(request.getMethod().toLowerCase())) { return true; }
String host = request.getHeader("host"); if (hostWhitelistSet.contains(host)) { return true; }
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); StringBuilder url = new StringBuilder(); if (request.isSecure()) { url.append("https://"); } else { url.append("http://"); } url.append(redirectHost); if (redirectPort != null && redirectPort != 80) { url.append(':').append(redirectPort); } url.append(request.getRequestURI()); String queryString = request.getQueryString(); if (queryString != null) { url.append('?').append(queryString); } response.setHeader("location", url.toString()); return false; }
public void addHostWhitelist(String host) { if (host == null) { return; } hostWhitelistSet.add(host); }
public String getRedirectHost() { return redirectHost; }
public void setRedirectHost(String redirectHost) { if (redirectHost == null) { return; } this.redirectHost = redirectHost; hostWhitelistSet.add(redirectHost); }
public Integer getRedirectPort() { return redirectPort; }
public void setRedirectPort(Integer redirectPort) { if (redirectPort == null || redirectPort < 1 || redirectPort > 65535) { return; } this.redirectPort = redirectPort; } }
|
使用如下, 在启动类中配置拦截器, 我们可以在白名单中配置主域名(主域名自动加入白名单)和localhost(用于本地开发)
1 2 3 4
| HostInterceptor hostInterceptor = new HostInterceptor(); hostInterceptor.setRedirectHost("www.abc.com"); hostInterceptor.addHostWhitelist("localhost"); registry.addInterceptor(hostInterceptor).addPathPatterns("/**");
|