普通视图
南向资金净买入额达100亿港元
大摩:英伟达、AMD、特斯拉等客户需求爆表,台积电3nm抢手紧急扩产
机构:2032年全球电子传感器市场将达412亿美元
TCL华星明年印刷OLED出货量将达百万级
如何在Windows上使用SANE扫描文档
SANE是用于连接文档扫描仪的一套API,主要用于UNIX系统。与TWAIN(另一种主要用于Windows的文档扫描API)相比,它有几个优点:
- TWAIN不会将用户界面与设备的驱动程序分开。这样很难通过网络访问图像捕获设备。而SANE则可以轻松地在纯命令行环境中使用。
- SANE内置了对各种扫描仪的支持,而使用TWAIN必须下载并安装单独的驱动程序。
有一些在Windows上运行SANE的尝试。但大多数做法仍然需要Linux环境。借助Windows的Linux子系统(WSL),这一过程变得更加容易。
继续阅读以了解如何做到这一点。
将USB设备连接到WSL
-
安装Linux WSL发行版后,将其版本设置为2以使用WSL 2。
PS C:\Users\admin> wsl -l -v NAME STATE VERSION Debian Running 1 PS C:\Users\admin> wsl --set-version Debian 2 -
在Windows上安装USBIPD。可以在GitHub上找到它的安装程序。
-
使用USBIPD将USB设备连接到WSL。
PS C:\Users\admin> usbipd list # list USB devices connected to the host PS C:\Users\admin> usbipd bind --busid <busid> # share the device. You can find the bus id in the previous step PS C:\Users\admin> usbipd attach --wsl --busid <busid> # attach the device to WSL -
在Linux中运行
lsusb,可以在列表中找到USB设备。$ lsusb Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 002 Device 003: ID 04c5:132e Fujitsu, Ltd fi-7160
使用SANE扫描文档
-
安装SANE。这里,我们的系统是Debian。
$ sudo apt install sane-utils -
使用
scanimage命令行工具列出扫描仪和扫描文档。$ scanimage -L device 'fujitsu:fi-7160:151477' is a FUJITSU fi-7160 scanner $ scanimage -o scanned.png # save the document to an image
在浏览器中扫描文档
接下来,我们将使用Dynamic Web TWAIN SDK创建一个网页,在Windows上的浏览器中扫描文档,并使用WSL中运行的SANE后端。
-
在WSL上,安装Dynamic Web TWAIN服务。可以在它的npm包上找到安装程序。
sudo dpkg -i DynamicWebTWAINServiceSetup.deb该服务将作为HTTP服务器在网页和扫描仪之间进行通信。您可以通过访问http://127.0.0.1:18625来检查它是否已安装。
每次系统启动时,还需要启动两个进程。以下是启动它们的命令:
nohup "/opt/dynamsoft/Dynamic Web TWAIN Service 19/DynamsoftScanning" gtkproxy & nohup "/opt/dynamsoft/Dynamic Web TWAIN Service 19/DynamsoftScanningMgr" &可以自己创建一个服务来启动它们。
-
使用以下代码编写一个网页来扫描文档并另存为PDF:
<!DOCTYPE html> <html> <head> <title>Scan via SANE on Windows</title> <script src="https://cdn.jsdelivr.net/npm/dwt@latest/dist/dynamsoft.webtwain.min.js"></script> </head> <body> <button onclick="AcquireImage();">Scan</button> <button onclick="SaveAsPDF();">Save as PDF</button> <div id="dwtcontrolContainer"></div> <script type="text/javascript"> Dynamsoft.DWT.Host = "local.dynamsoft.com"; Dynamsoft.DWT.ResourcesPath = "https://cdn.jsdelivr.net/npm/dwt@latest/dist"; //You need to set the service installer location here since the installer's size exceeds jsdelivr's limit. //You'd better host the installers in your own environment. Dynamsoft.DWT.ServiceInstallerLocation = 'https://unpkg.com/dwt/dist/dist/'; Dynamsoft.DWT.ProductKey = 'LICENSE-KEY'; Dynamsoft.DWT.Containers = [{ ContainerId: 'dwtcontrolContainer', Width: 270, Height: 350 }]; window.onload = function () { Dynamsoft.DWT.Load(); }; var DWTObject; Dynamsoft.DWT.RegisterEvent("OnWebTwainReady", function() { // dwtcontrolContainer is the id of the DIV to create the WebTwain instance in. DWTObject = Dynamsoft.DWT.GetWebTwain('dwtcontrolContainer'); }); function AcquireImage() { if (DWTObject) { DWTObject.SelectSourceAsync().then(function(){ return DWTObject.AcquireImageAsync({ PixelType: Dynamsoft.DWT.EnumDWT_PixelType.TWPT_RGB, Resolution: 200, IfCloseSourceAfterAcquire: true }); }).catch(function (exp) { alert(exp.message); }); } } function SaveAsPDF(){ if (DWTObject) { DWTObject.ConvertToBlob( DWTObject.SelectAllImages(), Dynamsoft.DWT.EnumDWT_ImageType.IT_PDF, function (result, indices, type) { console.log(result.size); DownloadBlobAsFile(result, "scanned_document.pdf"); }, function (errorCode, errorString) { console.log(errorString); }, ); } } function DownloadBlobAsFile(blob, fileName) { var link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = fileName; link.click(); } </script> </body> </html>
![]()
现在,我们可以使用SANE在Windows上扫描文档了。
源代码
东盟首超欧盟成浙江最大贸易市场
中创新航发布顶流“全能”圆柱电池,可应用于乘用车、eVOLT等多个领域
英伟达支持的澳大利亚人工智能公司Firmus融资3.25亿美元
“十四五”期间三峡后续工作规划实施项目1235个
中国通号研发的ETCS-400T车载产品获奥地利官方运营许可
面试官:JWT、Cookie、Session、Token有什么区别?
JWT、Cookie、Session、Token 是 Web 开发中常用的身份认证和状态管理技术,它们之间既有区别,也有联系
一、JWT(JSON Web Token)
JWT 是一种开放标准(RFC 7519),用于在网络应用之间安全地传输信息(通常是身份认证信息)。它是一个自包含的、可验证的、不可篡改的字符串,格式如下:
Header.Payload.Signature
三部分组成:
- Header(头部):声明类型和签名算法(如 HS256)。
- Payload(载荷):包含用户信息(如用户 ID、角色等)和元数据(如过期时间)。
- Signature(签名):用密钥对 Header 和 Payload 签名,防止篡改。
特点:
- 无需服务器存储(无状态)。
- 可跨域使用(常用于分布式系统、微服务)。
- 一旦签发,在过期前无法撤销(除非引入黑名单机制)。
二、Cookie
Cookie 是浏览器存储的一小段文本信息,由服务器通过 HTTP 响应头 Set-Cookie 设置,浏览器在后续请求中自动携带。
特点:
- 自动携带(浏览器行为)。
- 可设置过期时间、作用域、HttpOnly、Secure 等属性。
- 容量小(约 4KB)。
- 可用于存储 Session ID 或 JWT。
三、Session(会话)
Session 是服务器端维护的用户会话状态。通常流程如下:
- 用户登录后,服务器创建一个 Session,生成一个唯一的 Session ID。
- Session ID 通过 Cookie 返回给浏览器。
- 浏览器后续请求自动携带该 Cookie,服务器通过 Session ID 查找对应的用户状态。
特点:
- 状态存储在服务器端(通常是内存、Redis、数据库)。
- 安全性较高(用户无法直接篡改)。
- 不适合分布式系统(需要共享 Session 存储)。
四、Token(令牌)
Token 是一个广义概念,指用于身份验证的凭证。JWT 就是一种 Token。
常见 Token 类型:
- Access Token(访问令牌):用于访问资源。
- Refresh Token(刷新令牌):用于获取新的 Access Token。
- JWT:一种结构化的 Token。
五、它们之间的关系与区别
| 名称 | 存储位置 | 状态管理 | 安全性 | 适用场景 |
|---|---|---|---|---|
| JWT | 客户端 | 无状态 | 中 | 分布式系统、移动端、API 认证 |
| Cookie | 客户端 | 无状态 | 低 | 存储小量数据、自动携带 |
| Session | 服务器端 | 有状态 | 高 | 传统 Web 应用 |
| Token | 客户端 | 无状态 | 中 | 通用身份凭证(JWT 是其一) |
六、常见组合方式
方式一:Session + Cookie(传统 Web)
- 登录后服务器创建 Session,Session ID 存 Cookie。
- 每次请求带 Cookie,服务器查 Session 验证身份。
方式二:JWT + Header(前后端分离)
- 登录后服务器返回 JWT,前端存 localStorage 或 Cookie。
- 每次请求手动在 Header 中加
Authorization: Bearer <JWT>。
方式三:JWT + Cookie(安全增强)
- JWT 存 Cookie,设置 HttpOnly + Secure,防止 XSS。
- 浏览器自动携带,服务器解析 JWT 验证身份。
七、总结
- JWT 是一种自包含的 Token,不依赖服务器存储。
- Cookie 是浏览器存储机制,可存 Session ID 或 JWT。
- Session 是服务器存储的用户状态,依赖 Cookie 传递 ID。
- Token 是身份凭证,JWT 是其中一种实现。