重定向
重定向的分为两种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("/**");
|