最近的一個項目要在手機淘寶客戶端裏面開發網頁,因爲淘寶目前全站https,因此在開發環境搭建時候遇到了以前沒有料想到的一些問題,這裏分享一下此次踩坑的經歷。javascript
在這個項目當中使用了 webpack 做爲模塊加載器,使用 webpack 進行前端開發通常會同時使用 webpack-dev-server 來提升開發的效率。前端
webpack-dev-server 會利用 Express 創建一個服務器,將打包後的 js 文件 引入到頁面當中,即時反映對文件的修改。java
在配置好 webpack 以後,運行以後發現 webpack-dev-server 加載的 js 文件並不能在頁面上顯示。通過一番研究以後發現這裏涉及到了 https 的 Mixed Content 問題。node
若是一個 HTTPS 網頁當中有請求 HTTP 的資源,這種網頁就被稱爲 Mixed Content Page。webpack
Mixed Content 被分爲兩類 Optionally-blockable Content 和 Blockable Content。ios
Optionally-blockable Content 包括一些引入風險較低的資源:git
<img>github
<audio>web
<video>瀏覽器
在現代的瀏覽器當中這些資源即時不是經過 https 引用也會被加載到頁面當中。
而其餘的引入風險較高的資源就被稱爲 Blockable Content,包括 <script>、<link>、<iframe> 等。這些資源若是是經過 http 協議引用的話是不會被加載到頁面當中的。
既然知道問題所在,解決的方法也就很是簡單了,修改一下 webpack-dev-server 的配置,啓用 https 協議。
new WebpackDevServer(webpack(config), { // 省略其他代碼 https: true // 啓用 https }).listen(3000, function(err, res) {});
啓用了 https 協議以後,依然沒法正常訪問 webpack 打包的資源。在桌面瀏覽器訪問一些 https 網站時候常常會看到這樣的畫面:
出現這個畫面的緣由是網站的證書不受信任,在桌面端的瀏覽器能夠點擊繼續前往來訪問不受信任的資源。而在移動端的瀏覽器除了少數的瀏覽器(如:uc瀏覽器)能夠訪問不受信任的資源以外,大部分的瀏覽器會直接禁止訪問。
要在手機瀏覽器上訪問 https 協議的 webpack-dev-server 服務器上面的資源,就要安裝匹配服務器的證書。
打開 node-module 找到 webpack-dev-server 會發現一個叫 ssl 的文件夾,這就是用來放置 webpack-dev-server 證書的地方。
如今把客戶端用的 ca.crt 證書安裝到手機上,搞定。
安裝完證書以後再打開手機淘寶,發現靜態資源依然不能訪問,打開手機安裝的證書發現 webpack-dev-server 的證書已通過期了T_T。
再看看 webpack-dev-server github 的項目,發現這些證書最近的更新是一年前。看來如今只能本身去生成新的自簽證書了。
查看 webpakc-dev-server 的代碼:
// using built-in self-signed certificate if no certificate was configured options.https.key = options.https.key || fs.readFileSync(path.join(__dirname, "../ssl/server.key")); options.https.cert = options.https.cert || fs.readFileSync(path.join(__dirname, "../ssl/server.crt")); options.https.ca = options.https.ca || fs.readFileSync(path.join(__dirname, "../ssl/ca.crt"));
要替代原來的證書須要生成這三個文件。
生成自籤的證書最多見的方法就是用 OpenSSl 工具,在 Mac OSX 上面默認已經安裝了。
首先要生成一個證書頒發機構(CA)根證書,利用這個根證書能夠建立客戶端使用的證書,還須要用根證書去對服務端使用的證書進行簽名。
建立CA證書首先建立私鑰文件,2048指的是私鑰的位數:
openssl genrsa -out CA.key 2048
而後建立證書:
openssl req -x509 -new -key CA.key -out CA.crt -days 730
建立證書的過程中須要填寫一系列的信息,其中要留意 Common Name 須要填寫服務器的域名,通過我的的測試在安卓機上即便證書是被信任的,可是 Common Name 的域名並不對應的話資源一樣是沒法訪問的。CA.crt 已經能夠發送到移動設備上面使用了。
而後建立服務端使用的證書。一樣先建立私鑰文件:
openssl genrsa -out server.key 2048
而後建立一個證書請求,填寫與CA根證書相應的信息:
openssl req -new -out server.req -key server.key
利用CA證書籤發服務端使用的證書:
openssl x509 -req -in server.req -out server.crt -CAkey CA.key -CA CA.crt -days 365 -CAcreateserial -CAserial serial
最後把生成的證書替換 ssl 文件夾裏面的內容,大功告成,webpack-dev-server 上的資源能夠成功訪問了。
參考
本文同步於個人我的博客 http://blog.acwong.org/2016/03/05/change-webpack-certificate/