使用HTTPS 服務在瀏覽器端使用攝像頭的方式解析

1.方式1

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import basicSsl from '@vitejs/plugin-basic-ssl'export default defineConfig({plugins: [vue(),basicSsl({name: 'test',domains: ['192.168.15.166', 'localhost'], // 添加您的IPcertDir: './cert',}),],server: {host: '0.0.0.0',port: 3000,https: true,proxy: {'/api': {target: 'http://localhost:5000',changeOrigin: true,},},},build: {outDir: 'dist',assetsDir: 'assets',sourcemap: false,minify: 'terser',rollupOptions: {output: {chunkFileNames: 'js/[name]-[hash].js',entryFileNames: 'js/[name]-[hash].js',assetFileNames: '[ext]/[name]-[hash].[ext]',},},},
})

2.方式2

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import fs from 'fs'
import path from 'path'export default defineConfig({plugins: [vue(),],server: {https: {key: fs.readFileSync(path.resolve(__dirname, 'cert/key.pem')),cert: fs.readFileSync(path.resolve(__dirname, 'cert/cert.pem'))},host: '0.0.0.0',port: 3000,proxy: {'/api': {target: 'http://localhost:5000',changeOrigin: true},},},build: {outDir: 'dist',assetsDir: 'assets',sourcemap: false,minify: 'terser',},
})

這兩個 Vite 配置文件都實現了 HTTPS 服務,這是瀏覽器訪問攝像頭等敏感設備的必要條件。以下詳細解釋它們的原理和差異。

為什么需要 HTTPS

現代瀏覽器出于安全考慮,要求在以下情況下才能訪問攝像頭、麥克風等敏感設備:

  • 使用 HTTPS 協議(安全連接)
  • 或者是 localhost 域名(本地開發特例)

這是因為 getUserMedia() API 被歸類為"強大功能"(Powerful Features),需要安全上下文(Secure Context)。

方式一:使用 @vitejs/plugin-basic-ssl 插件

plugins: [vue(),basicSsl({name: 'test',domains: ['192.168.31.179', 'localhost'],certDir: './cert',}),
]

原理:

  1. 自動生成證書:插件會自動為指定的域名生成自簽名 SSL 證書
  2. 證書存儲:生成的證書存儲在 ./cert 目錄中
  3. 多域名支持:可以為多個域名/IP 生成證書(如局域網 IP 和 localhost)
  4. 自動配置:插件會自動將證書配置到 Vite 的 HTTPS 服務器

工作流程:

  • 首次運行時,插件檢查證書是否存在
  • 如果不存在,使用內置的證書生成器創建自簽名證書
  • 將證書自動注入到 Vite 的 server 配置中
  • 后續運行時復用已生成的證書

方式二:手動配置證書

server: {https: {key: fs.readFileSync(path.resolve(__dirname, 'cert/key.pem')),cert: fs.readFileSync(path.resolve(__dirname, 'cert/cert.pem'))},
}

原理:

  1. 手動管理證書:需要預先生成或獲取 SSL 證書文件
  2. 文件讀取:使用 Node.js 的 fs 模塊直接讀取證書文件
  3. 直接配置:將證書內容直接傳遞給 Vite 的 HTTPS 配置

證書生成方式(通常使用 OpenSSL):

# 生成私鑰
openssl genrsa -out key.pem 2048
# 生成證書
openssl req -new -x509 -key key.pem -out cert.pem -days 365

關鍵差異對比

特性方式一(plugin-basic-ssl)方式二(手動配置)
便利性高 - 自動生成和管理低 - 需要手動創建證書
靈活性中等 - 插件預設配置高 - 完全自定義
證書類型自簽名證書可以使用任何證書(自簽名或CA簽發)
多域名支持內置支持,配置簡單需要生成包含 SAN 的證書
首次設置零配置,自動完成需要手動生成證書
團隊協作每個開發者自動生成需要共享證書文件
證書更新刪除舊證書即可重新生成手動重新生成和替換
依賴性需要安裝額外插件僅需 Node.js 內置模塊

實際應用場景

方式一適合:

  • 本地開發環境
  • 快速原型開發
  • 需要在局域網內多設備測試
  • 團隊成員各自開發,不共享證書

方式二適合:

  • 需要使用特定證書(如公司內部 CA 簽發)
  • 生產環境的本地模擬
  • 需要精確控制證書配置
  • 已有證書管理流程的團隊

瀏覽器訪問攝像頭的實現

無論使用哪種方式,配置 HTTPS 后都可以使用以下代碼訪問攝像頭:

navigator.mediaDevices.getUserMedia({ video: true, audio: true 
})
.then(stream => {// 獲取到媒體流videoElement.srcObject = stream;
})
.catch(err => {console.error('無法訪問攝像頭:', err);
});

注意事項

  1. 證書信任:兩種方式生成的自簽名證書都會導致瀏覽器警告,需要手動信任
  2. 局域網訪問:方式一通過配置 IP 地址,可以讓局域網內其他設備通過 HTTPS 訪問
  3. 安全性:這些配置僅適用于開發環境,生產環境應使用正規 CA 簽發的證書

總的來說,方式一更適合快速開發和原型驗證,方式二則提供了更多的控制權和靈活性。選擇哪種方式主要取決于項目需求和團隊的技術偏好。

這是使用自簽名證書進行本地開發時的常見問題。讓我詳細說明解決方案:

一、手機無法訪問的問題排查

1. 確保網絡連通性

// vite.config.js
server: {host: '0.0.0.0',  // 允許外部訪問port: 3000,https: true,
}

檢查步驟:

  • 確保手機和電腦在同一局域網
  • 電腦防火墻允許 3000 端口
  • 使用電腦的局域網 IP(如 https://192.168.31.179:3000

2. 防火墻設置

# Windows - 以管理員運行
netsh advfirewall firewall add rule name="Vite Dev Server" dir=in action=allow protocol=TCP localport=3000# macOS
sudo pfctl -d  # 臨時關閉防火墻測試# Linux
sudo ufw allow 3000/tcp

二、手機端安裝證書的正確方法

iOS 設備

  1. 生成包含正確信息的證書:
# 創建證書配置文件 cert.conf
cat > cert.conf <<EOF
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no[req_distinguished_name]
C = CN
ST = State
L = City
O = Organization
CN = 192.168.31.179[v3_req]
keyUsage = critical, digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names[alt_names]
DNS.1 = localhost
IP.1 = 192.168.31.179
IP.2 = 127.0.0.1
EOF# 生成證書
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \-keyout key.pem -out cert.pem -config cert.conf
  1. 安裝證書到 iOS:
  • cert.pem 文件通過郵件/AirDrop 發送到手機
  • 點擊證書文件,選擇"安裝"
  • 設置 → 通用 → 關于本機 → 證書信任設置
  • 開啟對該證書的完全信任

Android 設備

  1. Android 安裝步驟:
  • cert.pem 重命名為 cert.crt
  • 傳輸到手機
  • 設置 → 安全 → 加密與憑據 → 安裝證書 → CA 證書
  • 選擇證書文件安裝

三、使用 mkcert 工具(推薦方案)

mkcert 可以創建本地受信任的證書,避免所有警告:

安裝 mkcert

# Windows (使用 Chocolatey)
choco install mkcert# macOS
brew install mkcert# Linux
apt install libnss3-tools
wget -O mkcert https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64
chmod +x mkcert
sudo mv mkcert /usr/local/bin/

配置本地 CA 并生成證書

# 1. 安裝本地 CA
mkcert -install# 2. 生成證書(包含所有需要的域名和 IP)
mkcert -cert-file cert.pem -key-file key.pem localhost 127.0.0.1 192.168.31.179 ::1# 3. 為手機生成 CA 證書
mkcert -CAROOT  # 顯示 CA 證書位置

更新 Vite 配置

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import fs from 'fs'
import path from 'path'export default defineConfig({plugins: [vue()],server: {https: {key: fs.readFileSync('./key.pem'),cert: fs.readFileSync('./cert.pem')},host: '0.0.0.0',port: 3000,}
})

手機端信任 mkcert CA

  1. 獲取 CA 證書:
# 找到 CA 證書位置
mkcert -CAROOT
# 通常在: 
# Windows: %LOCALAPPDATA%\mkcert
# macOS: ~/Library/Application Support/mkcert
# Linux: ~/.local/share/mkcert
  1. rootCA.pem 發送到手機并安裝

四、使用 ngrok(外網訪問方案)

如果證書問題難以解決,可以使用 ngrok 提供的 HTTPS 隧道:

# 安裝 ngrok
npm install -g ngrok# 啟動本地服務后,創建隧道
ngrok http 3000# 會得到類似這樣的地址:
# https://abc123.ngrok.io

優點:

  • 自動 HTTPS,無需證書配置
  • 可以外網訪問
  • 手機無需安裝證書

五、開發環境最佳實踐配置##

// vite.config.js - 完整的 HTTPS 配置方案
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import fs from 'fs'
import path from 'path'
import { execSync } from 'child_process'// 獲取本機局域網 IP
function getLocalIP() {const os = require('os')const interfaces = os.networkInterfaces()for (const name of Object.keys(interfaces)) {for (const iface of interfaces[name]) {if (iface.family === 'IPv4' && !iface.internal) {return iface.address}}}return '127.0.0.1'
}// 自動生成證書函數
function ensureCertificates() {const certDir = path.resolve(__dirname, 'cert')const keyPath = path.join(certDir, 'key.pem')const certPath = path.join(certDir, 'cert.pem')// 檢查證書是否存在if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {console.log('? 使用現有證書')return { key: keyPath, cert: certPath }}// 創建證書目錄if (!fs.existsSync(certDir)) {fs.mkdirSync(certDir, { recursive: true })}const localIP = getLocalIP()console.log(`📱 局域網 IP: ${localIP}`)// 檢查是否安裝了 mkcerttry {execSync('mkcert -version', { stdio: 'ignore' })console.log('🔧 使用 mkcert 生成受信任的證書...')// 安裝本地 CA(如果還沒安裝)execSync('mkcert -install', { stdio: 'inherit' })// 生成證書execSync(`mkcert -cert-file ${certPath} -key-file ${keyPath} localhost 127.0.0.1 ${localIP} ::1`,{ stdio: 'inherit' })console.log('? mkcert 證書生成成功!')console.log('📱 手機端請安裝 CA 證書:')const caRoot = execSync('mkcert -CAROOT').toString().trim()console.log(`   ${path.join(caRoot, 'rootCA.pem')}`)} catch (e) {console.log('??  mkcert 未安裝,使用 OpenSSL 生成自簽名證書...')// 創建 OpenSSL 配置const configPath = path.join(certDir, 'openssl.cnf')const opensslConfig = `
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no[req_distinguished_name]
C = CN
ST = State
L = City
O = Dev Organization
CN = ${localIP}[v3_req]
keyUsage = critical, digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names[alt_names]
DNS.1 = localhost
DNS.2 = *.localhost
IP.1 = 127.0.0.1
IP.2 = ${localIP}
IP.3 = ::1
`fs.writeFileSync(configPath, opensslConfig)// 生成證書try {execSync(`openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${keyPath} -out ${certPath} -config ${configPath}`,{ stdio: 'inherit' })console.log('? 自簽名證書生成成功!')console.log('??  瀏覽器會顯示安全警告,需要手動信任證書')} catch (error) {console.error('? 證書生成失敗:', error)process.exit(1)}}return { key: keyPath, cert: certPath }
}// 生成或獲取證書
const certificates = ensureCertificates()export default defineConfig({plugins: [vue()],server: {https: {key: fs.readFileSync(certificates.key),cert: fs.readFileSync(certificates.cert)},host: '0.0.0.0',  // 允許外部訪問port: 3000,// 顯示二維碼方便手機掃描open: false,// 配置 CORScors: true,// 代理配置proxy: {'/api': {target: 'http://localhost:5000',changeOrigin: true,secure: false,}}},// 構建配置build: {outDir: 'dist',assetsDir: 'assets',sourcemap: false,minify: 'terser',rollupOptions: {output: {chunkFileNames: 'js/[name]-[hash].js',entryFileNames: 'js/[name]-[hash].js',assetFileNames: '[ext]/[name]-[hash].[ext]',}}},// 優化配置optimizeDeps: {exclude: ['vue']}
})// 啟動后打印訪問信息
process.nextTick(() => {const localIP = getLocalIP()console.log('\n🚀 服務已啟動:')console.log(`   本地: https://localhost:3000`)console.log(`   局域網: https://${localIP}:3000`)console.log('\n📱 手機訪問提示:')console.log('   1. 確保手機與電腦在同一 WiFi')console.log('   2. 如有證書警告,點擊"高級"→"繼續訪問"')console.log('   3. iOS 需在"設置"→"通用"→"關于本機"→"證書信任設置"中信任證書\n')
})

六、配套的 package.json 腳本

{"scripts": {"dev": "vite","dev:host": "vite --host","dev:network": "vite --host 0.0.0.0","dev:https": "node scripts/setup-https.js && vite","cert:install": "mkcert -install","cert:generate": "mkcert -cert-file cert/cert.pem -key-file cert/key.pem localhost 127.0.0.1 $(ipconfig getifaddr en0 || hostname -I | awk '{print $1}') ::1","cert:trust": "mkcert -install && npm run cert:generate","build": "vite build","preview": "vite preview","tunnel": "ngrok http 3000"},"devDependencies": {"@vitejs/plugin-basic-ssl": "^1.0.1","@vitejs/plugin-vue": "^4.2.3","vite": "^4.3.9","vue": "^3.3.4"},"dependencies": {"qrcode": "^1.5.3"}
}

七、快速解決方案總結

最簡單的方案(推薦)

  1. 安裝 mkcert
# 一次性設置,永久解決證書問題
brew install mkcert  # macOS
mkcert -install
  1. 生成證書
mkcert -cert-file cert.pem -key-file key.pem localhost 192.168.xxx.xxx
  1. 手機端信任
  • ~/.local/share/mkcert/rootCA.pem(或對應系統路徑)發送到手機
  • 安裝為受信任的 CA 證書

故障排查清單

? 網絡連接

  • 手機和電腦同一 WiFi?
  • 防火墻允許 3000 端口?
  • 使用正確的 IP 地址?

? 證書配置

  • 證書包含局域網 IP?
  • 證書已安裝到手機?
  • iOS 已在"證書信任設置"中啟用?

? Vite 配置

  • host: '0.0.0.0' 已設置?
  • https: true 或手動配置證書?
  • 端口沒有被占用?

終極備用方案

如果以上都不行,使用 localtunnelngrok

npx localtunnel --port 3000 --subdomain myapp
# 或
ngrok http 3000

這樣可以獲得一個臨時的公網 HTTPS 地址,無需任何證書配置,手機可以直接訪問。

主要缺點是需要依賴外部服務,并且速度可能較慢。但對于緊急測試和演示,這是最快的解決方案。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/922357.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/922357.shtml
英文地址,請注明出處:http://en.pswp.cn/news/922357.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

上下文管理器和異步I/O

目錄 一、上下文管理器 1.1 定義 1.2 特點 1.3 適用場景 1.4 具體實現 1.5 具體實例 1.5.1 文件管理器 1.5.2 線程鎖釋放資源 二、異步I/O 2.1 定義 2.2 特點 2.3 實現方式 2.4 適用場景 高并發網絡服務&#xff1a;Web服務器、API服務等需要處理大量并發連接 2…

LabVIEW信號監測與分析

借助 LabVIEW 平臺&#xff0c;生成含正弦波與噪聲的信號&#xff0c;經頻譜分析等處理&#xff0c;結合動態限值判斷信號是否超限&#xff0c;廣泛用于音頻、振動等領域的信號監測&#xff0c;助力高效開展信號分析與質量把控。概念說明系統圍繞信號的生成、處理、分析及監測展…

MySQL數據庫與表的創建、修改及數據操作指南

精選專欄鏈接 &#x1f517; MySQL技術筆記專欄Redis技術筆記專欄大模型搭建專欄Python學習筆記專欄深度學習算法專欄 歡迎訂閱&#xff0c;點贊&#xff0b;關注&#xff0c;每日精進1%&#xff0c;與百萬開發者共攀技術珠峰 更多內容持續更新中&#xff01;希望能給大家帶來…

?new species of flying reptile1 discovered in Scotland?

Pterosaur: new species of flying reptile1 discovered in Scotland 蘇格蘭斯凱島發現新翼龍物種 考古學家們在蘇格蘭斯凱島發現了一個新的翼龍物種。這種獨特的飛行爬行動物生活在1.68 – 1.66億年前。 This flying reptile soared over the heads of dinosaurs2 when Scotla…

03 節點行為

審批流程圖如下圖&#xff0c;在此流程圖中&#xff0c;存在兩個UserTask節點&#xff0c;第一個節點是主管審批&#xff0c;第二個節點是產品經理審批&#xff0c;兩個節點中間有一個排他網關&#xff0c;此網關用來對主管審批的結果進行判斷&#xff0c;如果主管審批通過&…

深度卷積生成對抗網絡詳解與實現

深度卷積生成對抗網絡詳解與實現 0. 前言 1. 網絡架構 1.1 批歸一化 1.2 激活 1.3 上采樣 2. 構建 DCGAN 2.1 生成器 2.2 判別器 2.3 訓練 DCGAN 0. 前言 深度卷積生成對抗網絡 (Deep Convolutional Generative Adversarial Network, DCGAN) 是基于生成對抗網絡 (Generative A…

CF607B Zuma -提高+/省選-

CF607B Zuma codeforces 原鏈接 題目描述 Genos\texttt{Genos}Genos 最近在他的手機上下載了祖瑪游戲。在祖瑪游戲里&#xff0c;存在 nnn 個一行的寶石&#xff0c;第 iii 個寶石的顏色是 CiC_iCi?。這個游戲的目標是盡快的消滅一行中所有的寶石。 在一秒鐘&#xff0c;Ge…

拆分了解HashMap的數據結構

文章目錄 前言 一、底層數據結構總覽 二、核心組成部分詳解 1. 數組&#xff08;哈希表&#xff09; 2. 節點&#xff08;Node&#xff09; 3. 紅黑樹&#xff08;TreeNode&#xff09; 三、哈希函數與索引計算 四、哈希沖突的解決 五、擴容機制 六、關鍵特性與注意事…

關于電腦連接不到5g的WiFi時的一些解決辦法

方法一、設備管理器重卸載驅動后&#xff0c;重裝驅動。方法二、打開控制面板 “控制面板\網絡和 Internet\網絡連接” &#xff08;親測有效&#xff09;點擊更改適配器配置右擊當前的WLAN屬性點擊配置選擇“高級” 802.11a/b/g 無線模式選項欄 值&#xff1a;6.的雙…

Mathtype公式批量編號一鍵設置公式居中編號右對齊

插件[ygtools] 批量編號一鍵設置公式居中編號右對齊 單欄/多欄均可https://wwon.lanzout.com/i0NRf35vyw8j 下載密碼8543

基于ssm的小橘子出行客戶體驗評價系統[SSM]-計算機畢業設計源碼+LW文檔

摘要&#xff1a;隨著出行行業的快速發展&#xff0c;客戶體驗評價對于出行服務質量的提升至關重要。本文設計并實現了基于SSM&#xff08;Spring Spring MVC MyBatis&#xff09;框架的小橘子出行客戶體驗評價系統。該系統涵蓋系統用戶管理、司機信息管理、客戶評價管理等功…

算法日記---二分查找

目錄 前言 一、二分查找 1.思想 2.簡單二分 3.優點 4.局限性 二、模板 1.基本模板 2.簡單例題&#xff08;LeetCode&#xff09; 4.有重復元素的二分 5.0-1問題 總結 前言 本文通過講解簡單的二分查找配合leetcode例題對二分查找本質、模板進行了基礎的總結 提示&a…

Level Set(水平集)算法——形象化講解

目錄 維度一&#xff1a;核心思想與比喻&#xff08;它像什么&#xff1f;&#xff09; 維度二&#xff1a;要解決什么問題&#xff1f;&#xff08;它能干嘛&#xff1f;有什么用&#xff1f;&#xff09; 維度三&#xff1a;工作原理&#xff08;它是怎么做到的&#xff1…

DDoS 攻防“軍備競賽”的幕后

談到 DDoS&#xff08;分布式拒絕服務攻擊&#xff09;&#xff0c;很多人會想到“黑客租用肉雞發流量&#xff0c;網站直接崩”。但事實上&#xff0c;如今的 DDoS 攻防早已變成一場 軍備競賽。攻擊者的武器越來越“工業化”&#xff1a;僵尸網絡商品化&#xff1a;黑市上&…

如何用 Rust 重寫 SQLite 數據庫(二):是否有市場空間?

用 Rust 實現一個類似 SQLite 的嵌入式數據庫非常有意義&#xff0c;但需要結合具體目標和場景來評估其價值。以下從技術、生態、市場需求和個人成長等多個維度展開分析&#xff0c;并給出結論。一、技術價值&#xff1a;Rust 與數據庫的天然契合 SQLite 作為全球裝機量最大的數…

【Web】ImaginaryCTF 2025 wp

目錄 imaginary-notes certificate codenames-1 passwordless pearl imaginary-notes I made a new note taking app using Supabase! Its so secure, I put my flag as the password to the "admin" account. I even put my anonymous key somewhere in the si…

oracel如何找到外鍵子表

要找到導致外鍵約束沖突的子表&#xff08;即包含"child record"的表&#xff09;&#xff0c;可以通過以下SQL查詢在Oracle數據庫中定位&#xff1a;1. 查詢約束基本信息&#xff08;確定父表和子表&#xff09;SELECT owner, constraint_name, table_name AS child…

智源研究院新研究:突破物理世界智能邊界的RoboBrain 2.0,將重構具身AI能力天花板

當你對著家用機器人說"把杯子放在筆筒和鍵盤之間&#xff0c;對齊杯身logo"時&#xff0c;它能精準理解空間關系并執行動作&#xff1b;當多臺機器人在超市協作補貨時&#xff0c;它們能自主規劃軌跡、避免沖突并完成長周期任務——這些曾經出現在科幻電影中的場景&a…

【2025】Office核心組件Microsoft word,Excel,PowerPoint詳細使用指南

Office 核心組件使用指南 Microsoft Word 文字處理 Word主要用于創建和編輯文檔&#xff0c;如信件、報告、論文等。 2025Office&#x1f517; 1. 界面認識 快速訪問工具欄&#xff1a;位于左上角&#xff0c;可自定義保存、撤銷、恢復等常用命令。功能區&#xff1a;頂部…

【模型訓練篇】VeRL的使用 - RL(PPO)與源碼

繼續學習字節家的VeRL&#xff0c;今天來看看VeRL的RL&#xff0c;是VeRL系列的第三篇文章&#xff08;話說近期好多大事兒&#xff0c;我司發布了Longcat、韓立結嬰、阿里周五發布了QWen-Next都是好東西啊&#xff0c;學不過來了damn&#xff09; 底層分布式能力基礎Ray&…