跳到主要内容
  1. Skills/
  2. 建站/

如何将网站从http升级到https

··字数 2984·6 分钟
howto

当前,在浏览器输入网址进行访问时,所有现代的浏览器默认都是访问 https 协议进行访问。这几年,大量非 https 网站刚已经升级到 https,搜索引擎、浏览器都偏爱 https 站点,再过几年,基本就不会有人谈 http 升级到 https 的问题了。

如果你是网站的访问者,只须知道 https 方式具有非常高的安全性,由浏览器和网站提供安全服务,除网站外,别人不知道你向网站发送了什么数据,别人也不知道网站向你发送了什么数据,反而是非 https 网站要引起你对安全的注意。

而如果你是网站的建设者,须要将网站升级到 https,不然现代浏览器都会对访问用户进行安全的风险信息提示,会影响网站访问量。

在将网站升级到 https 之前,首先申请 ssl 证书。关于 ssl 证书申请,请看有悟文章

其实部署 https 站点还是非常简单的,基本上站长都有使用 nginx 和 apache 做为 web 服务器,它们老早就支持 https 服务。只要申请好 ssl证书并部署好,在 nginx 和 apache 上指定 ssl 证书路径,启动就可以。

因为有悟建站时,没有默认全站启用 https ,导致部分网页地址或者 css 资源文件是 http 。要升级到 https,

  1. 要么就是放弃之前所有的 http 网址,但是对于搜索引擎来说,会出现大量404
  2. 要么就是全站启用 https,然后在 nginx 服务器的配置上将原 http 网址重定向到 https 上来。

重定向 #

至此,引出了 web 服务重定向的问题。实现 web 访问服务重定向的技术有很多,比如随便想到的就有这些方法:

  1. 在 https 页面上使用 meta 标记,
<meta http-equiv="refresh" content="0;URL='https://新网址'" 
  1. 在页面上使用 js 脚本,在网页文件加载后执行 window.location.replace(新的 https 网址),让网页自动跳转到的 https 网址
<html>
<body>
<script type="text/javascript">
    // Javascript 跳转到新网址
    window.location.replace("https://新的https网址");
</script>
</body>
</html>
  1. 将原网站部署到新的 https web 服务下,然后对所有的老网址都启用 类似于下面的网址迁移信息提示。
<html>    
<head>      
<meta http-equiv="refresh" content="2;URL='新网址'" />  </head>    
<title>原网页文件标题</title>      
<body> 
    <p>
        原网页已经迁移至
        <a href="https://新的网址/">新的网址</a>
    </p> 
</body>  
</html>     
  1. 若不想动前端页面那么麻烦,那么可以在服务器端配置上动心思,比如 nginx 的配置
...
    location /hot {

        rewrite ^旧的网址前缀(.*)$ https://新网址/$1 permanent;
    }
...

上面所列的重定向方法,应该根据自己实际情况来选择。比如只是对于一两个网页而言(通常是删除掉网站中的那些旧文章),采用网页插入 js 或者 html meta refresh 标记比较方便;而若是因为网址整合或者公司整并,要放弃原旧网站,最方便就是弄个提示网站,并说明原因,然后给出来新链接让用户点击。而若是像有悟一样,想整重向到 https 上的,可以看下一节文章。

这里有个重要事项需要提醒,如果你的网站是内部网站那无关系,但如果你的网站对外服务,有 seo 的需求,那么旧网页的 canonical 一定要改到新网址上。这个提示放在这里好像不太合适,因为网址改变的发生并不限于重定向。有悟觉得有必要提醒。

<!-- 这是旧网页文件 -->
...
<link rel="canonical" href="https://域名/新的网址.html">
...

如何将 http 访问重定向到 https 上 #

有文章在升级全站 https 时,最主要要达到两个目的:

  1. 将 http 的访问直接重定向到 https 的对应网址上
  2. 有悟讨厌想使用 https://youwu.today 来替换 https://www.youwu.today 做为主站的网址

有悟使用 nginx 做 web 服务器,结合网站的情况,通过 nginx 来实现重定向最便捷,修改配置并简单测试后上线,过程就大概10几分钟。后面的配置都是有关 nignx 的。

1. 将 http 的访问重定向到 https 上 #

# /etc/nginx/site-avaible/youwu.today
# http -> https
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name *.youwu.today;
    return 301 https://$host$request_uri;
}

上面配置的意思是,在 server 级别站点配置上,监听 80 端口,接收到请求后,向客户端返回状态为 301 的重定向响应,告诉客户端按地址 https://$host$request_uri 重新请求。

配置中的 80 端口,一般服务器都以80 做为 http web 服务的标准端口号; *.youwu.today,是指不管是 abcd.youwu.today、还是 efg.youwu.today,都有效; $host 表示 *.youwu.today 配置到的域名; $request_uri 表的网址除掉域名后后面的部分,比如网址http://youwu.today/skill/buildsite?=abcd,那么 $request_uri 就是 /skill/buildsite?=abcdreturn 301 https://新的目标网址,告诉浏览器按新的网址重新访问一次,301 是 http status code,这里 301 表示网址已经永久迁移,是大家都遵守的规范,搜索引擎以后也不会再关注响应状态为301的网页。

上面只是给出拦截 80 端口的 http 访问,但要重定向能成功,确保 https://$host$request_uri 这个网址要真实存在。

# /etc/nginx/site-avaible/youwu.today
# http -> https
...
# ssl 443 端口的 https 服务
server {
    # server_name _;
    server_name youwu.today;

    index index.html index.htm;

    root /home/public/youwu.today;

    # SSL configuration
    #
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;
    ssl_certificate /证书路径/1_youwu.today_bundle.crt;
    ssl_certificate_key /证书路径/2_youwu.today.key;    
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; 
    ssl_prefer_server_ciphers on;
}

相对于 80 端口是http 服务的默认端口号,443 是 https 服务的默认端口号。 上面这段 443 server 的配置,就承接了 https 网页请求。

至此 http 就升级到 https 了。当然你需要事先准备好证书文件。

如果你是使用 为你的网站申请 ssl 证书 中所讲的 acme.sh 申请的 ssl证书,那拿到的证书就不像有悟例中所列的 1_youwu.today_bundle.crt2_youwu.today.key,而是拿到了 fullchain.cer域名.key域名.cer域名.csrca.cer 等这些文件。 配置 nginx ssl 时,其实提供是一个证书和一个密钥,对应 acme.sh 申请到的分别是 证书 fullchain.cer密钥 域名.key

2. 从 www 转为无 www #

上一节已经介绍了 nginx 重定向配置,有悟为了敲更短的地址,想把 www 省掉。插一句,这个无 www 并不是标准的主域网址,虽然很简单,但是 google 努力了很久,关于在 chrome 上是否显示省略 www 这个问题还是战斗了很久而没能统一用户需求,上个月还是公告后续 chrome (忘了版本号是90几以后)要显示原网址,不再为用户省略。

言归正传,直接上配置(在几前节的基础上加)

# /etc/nginx/site-avaible/youwu.today
# http -> https
...

# www -> non-www
server {
    listen 443 ssl;
    server_name www.youwu.today;
    return 301 https://youwu.today$request_uri;
}
...
# ssl 443 端口的 https 服务
server {
    # server_name _;
    server_name youwu.today;
...

重点在 www -> non-www 那一个 server,将按访问网址域名为 www.youwu.today 的 https 请求,向客户端报告使用 https://youwu.today$request_uri 格式的网址重新请求,这里的 return 301... 在前面介绍 http->https 时已经有介绍 。

可能有人会有疑问,301 重定向是向浏览器收到响应后,再由浏览器按新网址重新请求,客户端与服务器不是要来回两次完整的交互吗?是的。这样做的原因,是必要告诉客户端,后端服务器已经改变,从而规范客户端的访问行为,同样重定向一定不能影响用户的频繁访问。

如果你要重定向的网页非常多,而这些网页又是非常重要的内容,要么干脆提示用户切换到新的地址,要么就是使用 nginx 的代理功能。本文所述的方法,就是让客户端能够感知网页地址的改变。是否这样做,完全取决于你的需求。

有悟之所有选择 nginx 来配置 http-> https、www -> non-www,除了是因为 nginx 的配置便捷之外,还有就是本站已经大量使用 https 来做网址,由 http->https、www->non-www 而引起的重定向操作并不多,只占正常访问的非常少一部分。