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

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过浏览器调用摄像头失败: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。

<think>好的,我现在需要帮助用户了解如何在前端微信小程序中提交CSRF Token。用户之前已经询问过Django视图中的CSRF问题,现在他们可能正在开发一个微信小程序,需要与后端进行安全通信。 首先,我需要回忆一下Django中CSRF保护的机制。Django默认会检查POST请求中的CSRF Token,通常是从表单中的csrfmiddlewaretoken字段或者HTTP头中的X-CSRFToken获取。但在微信小程序中,不能直接使用传统的表单提交方式,可能需要通过请求头来传递Token。 接下来,我需要考虑微信小程序的环境限制。微信小程序的网络请求使用的是wx.request API,所以需要指导用户如何在这个环境中正确携带CSRF Token。用户可能需要先获取Token,然后存储它,之后在每个请求中附加。 用户可能不知道如何从Django后端获取CSRF Token。通常,Django会在响应中设置一个Cookie,名称默认是csrftoken。所以,在首次请求时,比如GET请求,后端会返回这个Cookie,前端需要读取并保存,然后在后续的POST请求中将其放入请求头。 需要注意的是,微信小程序的wx.request默认不会自动携带Cookie,所以需要显式设置withCredentials为true。这可能会涉及后端配置,比如允许跨域请求携带凭证,需要设置CORS相关的头部,如Access-Control-Allow-Origin为具体的域名而不是通配符,以及Access-Control-Allow-Credentials为true。 然后,用户需要在小程序端处理Cookie。可能需要使用wx.setStorageSync来保存CSRF Token,并在每次请求时从存储中取出,添加到请求头中。例如,在wx.request的header里加入X-CSRFToken字段。 还需要考虑安全性问题,比如确保使用HTTPS,避免中间人攻击。同时,提醒用户不要将CSRF Token暴露在日志或客户端存储的不安全位置。 用户可能还会遇到一些常见问题,比如跨域问题导致的Cookie无法保存,这时候需要检查后端的CORS配置是否正确。另外,如果用户没有正确地在请求头中添加Token,后端会返回403错误,需要提示用户检查请求头设置。 最后,可能需要提供一个完整的示例代码,展示如何在小程序中实现获取和发送CSRF Token的流程,以及后端的相应配置,帮助用户一步步实现安全通信。</think>--- ### **微信小程序前端提交CSRF Token的完整方案** --- #### **一、CSRF Token基本原理** 在Web安全中,CSRF(跨站请求伪造)防护依赖服务端生成的唯一随机Token,要求客户端在请求中携带该Token。其验证逻辑满足: $$ \text{服务端Token} \equiv \text{客户端提交Token} $$ --- #### **二、微信小程序实现步骤** ##### **1. 获取CSRF Token** - **首次请求时从服务端获取** ```javascript // 发起GET请求获取CSRF Token(Django会自动设置Cookie) wx.request({ url: 'https://api.example.com/get_token/', method: 'GET', success(res) { // Django默认通过Cookie返回csrftoken console.log('CSRF Token已通过Cookie存储') } }) ``` ##### **2. 存储CSRF Token** - **从响应Cookie中提取** ```javascript // 需启用withCredentials以接收Cookie wx.request({ url: 'https://api.example.com/login/', method: 'POST', header: { 'Content-Type': 'application/json', 'X-CSRFToken': wx.getStorageSync('csrftoken') // 从本地存储读取 }, data: { username: 'user', password: 'pass' }, success(res) { console.log('请求成功') } }) ``` ##### **3. 提交请求时携带Token** - **通过请求头`X-CSRFToken`传递** ```javascript wx.request({ url: 'https://api.example.com/sensitive_action/', method: 'POST', header: { 'X-CSRFToken': wx.getStorageSync('csrftoken') // 关键安全字段 }, data: { ... }, success(res) { ... } }) ``` --- #### **三、Django服务端配置** ```python # settings.py # 允许跨域请求携带Cookie(必需) CORS_ALLOW_CREDENTIALS = True # 指定可信域名(需替换为小程序实际域名) CORS_ALLOWED_ORIGINS = [ "https://your-wechat-app-domain.com" ] # 自定义CSRF Cookie名称(可选) CSRF_COOKIE_NAME = "custom_csrftoken" ``` --- #### **四、数学验证模型** CSRF Token安全性取决于其熵值: $$ H = \log_2(N) $$ 其中$N$为Token可能的组合数。Django默认使用32字符的随机字符串,满足: $$ H = \log_2(62^{32}) \approx 191 \text{ bits} $$ 远超安全阈值$H \geq 128 \text{ bits}$。 --- #### **五、注意事项** 1. **强制HTTPS** ```python # settings.py CSRF_COOKIE_SECURE = True # 仅通过HTTPS传输Cookie ``` 2. **Token时效性** - Django默认会话期间有效,无需额外刷新 3. **避免客户端存储泄露** - 禁止将Token写入本地文件或日志 --- #### **六、完整流程示例** ```javascript // 微信小程序端完整调用链 // 步骤1:获取CSRF Token wx.request({ url: 'https://api.example.com/init/', method: 'GET', withCredentials: true, success() { // 步骤2:提交敏感请求 wx.request({ url: 'https://api.example.com/transfer/', method: 'POST', header: { 'X-CSRFToken': wx.getStorageSync('csrftoken') }, data: { amount: 100 }, success(res) { console.log('转账成功') } }) } }) ``` --- ### **总结** 通过Cookie自动获取+请求头手动提交的方式,既符合微信小程序网络API特性,又能满足Django的CSRF验证要求,最终实现安全系数满足: $$ \text{安全强度} = \min(H_{\text{token}}, H_{\text{HTTPS}}) \geq 128 \text{ bits} $$
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值