网站中的301重定向

重定向

重定向的分为两种301302, 这两种使用起来感觉差不多, 但是对搜索引擎来说是有区别的

  • 301 表示永久重定向, 搜索引擎收到301响应时会把旧的地址的权值传给新的, 所以当网站更改域名或者网站内部资源url改变时应该使用301重定向
  • 302 表示临时重定向, 顾名思义就是告诉搜索引擎, 这个新地址只是临时用一用

权值分散

当一个网站有多个域名的时候, 据个人经验, 应当把所以域名都重定向到一个主域名上, 例如abc.comwww.abc.comhome.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("/**");