服务器项目前端调用摄像头失败,浏览器调用摄像头失败:NotSupportedError Only secure origins are allowed...

在新版本的Webkit内核浏览器中,由于安全隐私考虑,使用getUserMedia调用摄像头必须在HTTPS环境下。文章介绍了遇到的NotSupportedError错误,并提供了调用摄像头的兼容代码,以及错误回调中可能出现的异常类型。

通过浏览器调用摄像头失败:NotSupportedError Only secure origins are allowed

错误报告

NotSupportedError Only secure origins are allowed (see: https://goo.gl/Y0ZkNV).

[Deprecation] getUserMedia() no longer works on insecure origins. To use this feature, you should consider switching your

application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.

错误原因

新发布的Webkit内核的浏览器(chrome谷歌浏览器、QQ浏览器)控制台会有这个提示,基于安全隐私问题,现在Webkit内核的浏览器共享视频、语音、经纬度坐标等必须通过https形式访问!也就是说须将http访问形式改造成https,如果项目/产品是基于通过Webkit内核的浏览器访问,可以参考 久久经验网 此前发布的经验分享:

经测试,IE浏览器、Firefox火狐浏览器均能正常调用。下面分享调用摄像头的程序测试代码(参考自segmentfault,作者wangsidney)。

程序代码

HTML代码

当前浏览器不支持video

拍照

Javascript代码

//访问用户媒体设备的兼容方法

function getUserMedia(constrains,success,error){

if(navigator.mediaDevices.getUserMedia){

//最新标准API

navigator.mediaDevices.getUserMedia(constrains).then(success).catch(error);

} else if (navigator.webkitGetUserMedia){

//webkit内核浏览器

navigator.webkitGetUserMedia(constrains).then(success).catch(error);

} else if (navigator.mozGetUserMedia){

//Firefox浏览器

navagator.mozGetUserMedia(constrains).then(success).catch(error);

} else if (navigator.getUserMedia){

//旧版API

navigator.getUserMedia(constrains).then(success).catch(error);

}

}

var video = document.getElementById("video");

var canvas = document.getElementById("canvas");

var context = canvas.getContext("2d");

//成功的回调函数

function success(stream){

//兼容webkit内核浏览器

var CompatibleURL = window.URL || window.webkitURL;

//将视频流设置为video元素的源

video.src = CompatibleURL.createObjectURL(stream);

//播放视频

video.play();

}

//异常的回调函数

function error(error){

console.log("访问用户媒体设备失败:",error.name,error.message);//访问用户媒体设备失败: NotFoundError The object can not be found here.

}

if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia){

//调用用户媒体设备,访问摄像头

getUserMedia(

{

video:{width:480,height:320}

},

success,

error

);

} else {

alert("你的浏览器不支持访问用户媒体设备");

}

//注册拍照按钮的单击事件

document.getElementById("capture").addEventListener("click",function(){

//绘制画面

context.drawImage(video,0,0,480,320);

});

失败回调函数errorCallback的参数error,可能的异常有:

AbortError:硬件问题

NotAllowedError:用户拒绝了当前的浏览器实例的访问请求;或者用户拒绝了当前会话的访问;或者用户在全局范围内拒绝了所有媒体访问请求。

NotFoundError:找不到满足请求参数的媒体类型。

NotReadableError:操作系统上某个硬件、浏览器或者网页层面发生的错误导致设备无法被访问。

OverConstrainedError:指定的要求无法被设备满足。

SecurityError:安全错误,在getUserMedia() 被调用的 Document上面,使用设备媒体被禁止。这个机制是否开启或者关闭取决于单个用户的偏好设置。

TypeError:类型错误,constraints对象未设置[空],或者都被设置为false。

### UniApp H5 调用 `getLocation` 失败的原因分析 在 UniApp 的 H5 平台中,当尝试调用 `uni.getLocation` API 时遇到错误提示 “Only secure origins are allowed”,这是由于浏览器的安全策略所导致。现代浏览器为了保护用户的隐私和安全,默认情况下仅允许 HTTPS 协议下的页面访问地理位置信息[^1]。 #### 错误原因解析 该问题的核心在于浏览器的安全机制限制了非加密连接(HTTP)下对敏感数据的获取操作。具体来说,“secure origin” 是指通过 HTTPS 或 localhost 访问的资源。如果应用运行在普通的 HTTP 下,则无法正常调用地理定位功能[^2]。 #### 解决方案一:切换到 HTTPS 环境 最直接有效的解决方案是将项目部署至支持 HTTPS 的服务器环境。HTTPS 提供了一种更安全的数据传输方式,能够满足浏览器对于“secure origin”的需求。可以通过以下方法实现: - **购买 SSL 证书**:为您的域名配置合法的 SSL/TLS 证书。 - **测试阶段使用本地调试工具**:某些开发工具如 Chrome 浏览器会自动信任基于 `localhost` 和 IP 地址的 HTTPS 请求,因此可以在开发环境中模拟 HTTPS 条件进行测试[^3]。 #### 解决方案二:利用第三方服务替代原生接口 如果暂时无法迁移到 HTTPS 上线环境,可以考虑借助外部服务商提供的 IP 定位能力作为备选方案。例如引用高德地图或其他类似的 SDK 实现大致位置查询功能。以下是采用高德 IP 定位的一个简单实例代码片段: ```javascript function getLocationByIP() { const url = 'https://restapi.amap.com/v3/ip'; uni.request({ url, data: { key: 'your_amap_api_key' }, // 替换为您申请的实际 Key 值 success(res) { console.log('Position Info:', res.data); }, fail(err) { console.error('Failed to fetch location by IP', err); } }); } ``` 需要注意的是这种方法精度较低,通常只适用于粗略范围内的业务场景而非精确坐标采集。 #### 配置检查事项 另外还需确认项目的 manifest 文件或者扩展 JSON 中已声明必要的权限项。比如确保如下字段存在并正确设置: ```json { "requiredPrivateInfos": ["location"] } ``` 此部分配置用于告知框架哪些私有信息会被请求访问以便于适配不同平台的行为差异。 --- ### 总结 综上所述,针对 UniApp 开发中的 H5 应用出现 `getLocation` 报错情况,推荐优先迁移至 HTTPS 生产环境下工作;而在特殊条件下可选用其他间接手段完成相应任务目标但需权衡其局限性。
### 安全来源定义 安全来源指的是通过HTTPS协议访问的网站,这类网站的数据传输经过加密处理,能够有效防止中间人攻击和其他形式的信息泄露。对于HTTP请求而言,由于其明文传输特性,在某些敏感操作上存在安全隐患,因此现代浏览器如Chrome对这些操作进行了限制[^1]。 ### Chrome浏览器的安全策略 当尝试调用地理位置API或其他涉及隐私的功能时,Chrome会检查当前网页是否来自可信源。如果发现不是,则阻止相应功能并抛出`Only secure origins are allowed`错误消息。这是因为非HTTPS连接可能被窃听或篡改,从而危及用户数据安全[^2]。 ### 部署环境差异分析 在开发阶段使用`http://localhost:8080`通常不会触发上述警告,因为本地回环接口被视为相对安全;然而一旦发布至公网服务器(例如阿里云ECS实例),即使端口号相同,只要是以HTTP方式提供服务就会受到该政策影响而无法正常使用地理定位等功能[^3]。 ### 解决方案建议 针对此类问题有几种可行的方法: #### 方法一:启用SSL/TLS证书 最推荐的做法就是为线上应用配置有效的SSL/TLS证书,使得URL前缀变为`https://`而非简单的`http://`。这不仅解决了权限受限的问题,同时也提升了整个系统的安全性水平。具体实施步骤如下所示: ```bash sudo apt-get update && sudo apt-get install certbot python3-certbot-apache -y # 对于Debian/Ubuntu系统安装CertBot工具 certbot --apache # 使用CertBot自动获取Let's Encrypt免费签发的一年期DV SSL证书,并完成Apache Web Server集成设置 ``` #### 方法二:调整浏览器设置(临时措施) 虽然这不是长久之计,但在特定场景下可以考虑放宽本机Chrome浏览器关于混合内容加载的行为偏好来绕过这个问题。不过需要注意的是这样做可能会带来潜在风险,所以仅限内部调试用途而不适合生产环境中采用。 进入地址栏输入`chrome://flags/#allow-insecure-localhost`找到相关选项将其状态更改为Enabled即可生效[^4]。
<think>根据用户查询,需要解决getLocation报错"Only secure origins are allowed"。此错误通常在使用Geolocation API时,在非安全的环境下(如HTTP)调用导致。 解决方法包括将站点迁移到HTTPS,或使用localhost进行本地开发。此外,现代浏览器要求安全上下文(secure context)以使用某些API,包括Geolocation。 由于用户要求参考之前的回答,但这是首次回答此问题,因此需提供完整解决方案。 步骤: 1. 解释错误原因:在非安全的环境(如HTTP)中尝试使用Geolocation API。 2. 解决方案: a. 在生产环境中使用HTTPS。 b. 在开发环境中,使用localhost(被浏览器视为安全源)或HTTPS。 c. 对于Android的WebView,需要配置安全设置。 同时,可以添加代码示例(使用JavaScript)来说明如何安全地调用getLocation。 注意:根据指令,数学公式用$...$,独立公式用$$...$$,但由于内容不涉及数学公式,可能不会涉及。但要确保代码块的格式。 另外,生成相关问题。 </think> ### 解决 getLocation 报错 "Only secure origins are allowed" 的方法 该错误是由于浏览器安全策略限制引起的:**现代浏览器要求通过 HTTPS 协议访问地理位置(Geolocation)API**。以下是详细解决方案: --- #### 1. 在生产环境中启用 HTTPS 这是最根本的解决方案。Geolocation API 仅允许通过 `https://` 或 `localhost` 调用: - **获取 SSL 证书**:从 [Let's Encrypt](https://letsencrypt.org/)(免费)或商业 CA 购买 - **服务器配置示例**(Nginx): ```nginx server { listen 443 ssl; server_name yourdomain.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/privkey.pem; # 强制HTTP跳转到HTTPS return 301 https://$host$request_uri; } ``` --- #### 2. 开发环境临时解决方案 本地调试时可使用以下方法: - **使用 localhost**:浏览器将 `http://localhost` 视为安全源 ```js // 在本地服务器运行时正常调用 navigator.geolocation.getCurrentPosition(success, error); ``` - **启用 Chrome 特殊标志**(仅开发使用): 1. 访问 `chrome://flags` 2. 搜索 `Insecure origins treated as secure` 3. 添加你的测试地址(如 `http://dev-site:8080`) 4. **注意**:上线前必须移除 --- #### 3. Android WebView 特殊处理 在 Android 应用中嵌入 WebView 时: ```java webView.setWebChromeClient(new WebChromeClient() { @Override public void onGeolocationPermissionsShowPrompt(...) { // 必须调用此回调授权 callback.invoke(origin, true, false); // true 表示允许 } }); // 添加权限声明到 AndroidManifest.xml <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> ``` --- #### 4. 备用检测方法(环境降级) 代码中添加安全环境检测逻辑: ```js function getLocation() { if (!navigator.geolocation) { alert("浏览器不支持定位功能"); return; } // 检查协议安全性 if (window.location.protocol !== 'https:' && !['localhost', '127.0.0.1'].includes(window.location.hostname)) { alert("请在HTTPS或localhost环境下使用定位"); return; } navigator.geolocation.getCurrentPosition( position => console.log("坐标:", position.coords), error => console.error("定位失败:", error.message) ); } ``` > **关键原理**:浏览器安全策略规定,敏感 API 只能在[安全上下文](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts)中调用[^1] --- #### 5. iOS Safari 额外注意 iOS 15+ 额外要求: - 必须使用用户手势触发定位请求(如点击事件) - 需在 `Info.plist` 中添加描述: ```xml <key>NSLocationWhenInUseUsageDescription</key> <string>需要获取您的位置以实现XX功能</string> ``` --- **总结实施步骤**: 1. 生产环境:配置 HTTPS 证书 2. 开发环境:使用 `localhost` 3. 移动端 WebView:显式请求权限 4. 代码中:添加协议安全检测
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值