Deprecated: parse_url(): Passing null to parameter #1 ($url) of type string is deprecated in /www/wwwroot/blog_qqvbc_com/usr/plugins/Access/Access_Core.php on line 339

Deprecated: parse_url(): Passing null to parameter #1 ($url) of type string is deprecated in /www/wwwroot/blog_qqvbc_com/usr/plugins/Access/Access_Core.php on line 392

Deprecated: parse_url(): Passing null to parameter #1 ($url) of type string is deprecated in /www/wwwroot/blog_qqvbc_com/usr/plugins/Access/Access_Core.php on line 394
Joyber 的博客


        $(".btn-copy-qrcode-image").click(function(e) {
            //复制图片功能
            var img = $('#' + $(this).data('target'))[0]   //tag: img
            var canvas = document.createElement('canvas')
            canvas.width = img.naturalWidth
            canvas.height = img.naturalHeight
            var ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0, 0)
            canvas.toBlob(async blob => {
                const data = [
                    new ClipboardItem({
                        [blob.type]: blob,
                    }),
                ];
                await navigator.clipboard.write(data)
                    .then(
                        () => {
                            simpleDialog({
                                msg: '复制成功'
                            })
                        },
                        () => {
                            simpleDialog({
                                msg: '复制失败,请右键选择【复制图像】'
                            })
                        }
                    );
            });
        })

toBlob报错
图片跨域问题,img元素加上这个属性 crossorigin="anonymous"

Failed to execute 'toBlob' on 'HTMLCanvasElement': Tainted canvases may not be exported...

文章转自张鑫旭博客,原文地址:https://www.zhangxinxu.com/wordpress/2021/08/file-system-access-api/

一、温故而知新
传统在Web端文件上传,都是使用file类型的表单input框:

<input type="file">

file input框

我们可以通过accept属性指定选择的文件类型,directory属性指定是否可以选择文件夹,capture属性指定前置或后置摄像头。

功能还是很强的。

具体可以见我之前这篇文章:“HTML input type=file文件选择二三事”

但是file输入框有个致命的缺点,就是 UI 太丑了,并且无法定制。

虽然使用

那有没有什么办法点击一个普通的按钮,也能触发文件选择呢?最好可以设置选择文件夹还是文件,设置选择的文件格式类型。

还真有,现代Web不断发展,出现了一个新的API,叫做 File System Access API,可以实现点击任意元素触发文件选择。

二、showOpenFilePicker方法
假设页面上有个按钮,其HTML如下所示:


则下面几行JavaScript代码就可以实现点击按钮出现文件选择:

button.addEventListener('click', function () {
    // 打开文件
    window.showOpenFilePicker();
});

真是简单又粗暴,直接又了当。

当然,我们也可以使用 showDirectoryPicker() 方法来选择文件夹。

button.addEventListener('click', function () {
    // 打开文件夹
    window.showDirectoryPicker();
});

由于两个API参数和作用类似,因此里只详细介绍文件的选择。

文件类型、多选与否的指定
showOpenFilePicker(options) 方法中是可以传参的,具体支持的参数如下:

其中,options是可选参数,支持下面这些属性:

multiple
布尔值,默认值是 false ,表示只能选择一个文件。
excludeAcceptAllOption
布尔值,默认值是 false ,表示是否排除下面 types 中的所有的accept文件类型。
types
可选择的文件类型数组,每个数组项也是个对象,支持下面两个参数:
description:表示文件或者文件夹的描述,字符串,可选。
accept:接受的文件类型,对象,然后对象的键是文件的MIME匹配,值是数组,表示支持的文件后缀。具体可以下面的示意。
例如下面的JS代码执行就是可以一次性选择多张本地桌面图片:

window.showOpenFilePicker({
    types: [{
        description: 'Images',
        accept: {
            'image/*': ['.png', '.gif', '.jpeg', '.jpg', '.webp']
        }
    }],
    // 可以选择多个图片
    multiple: true
});

三、演示-点击按钮选择并显示多图
上面知道了选择文件,但是如何处理选择后的文件呢,下面有个例子,对大家学习会很有帮助。

完整代码如下:

<button id="button">选择图片</button>
<p id="output"></p>
button.addEventListener('click', async function () {
    // 打开文件
    const arrFileHandle = await window.showOpenFilePicker({
        types: [{
            accept: {
                'image/*': ['.png', '.gif', '.jpeg', '.jpg', '.webp']
            }
        }],
        // 可以选择多个图片
        multiple: true
    });
    
    // 遍历选择的文件
    for (const fileHandle of arrFileHandle) {
        // 获取文件内容
        const fileData = await fileHandle.getFile();
        // 读文件数据
        const buffer = await fileData.arrayBuffer();
        // 转成Blod url地址
        let src = URL.createObjectURL(new Blob([buffer]));
        // 在页面中显示
        output.insertAdjacentHTML('beforeend', `<img src="${src}">`);
    }
});

这个例子有对应的demo,您可以狠狠地点击这里:文件访问API 触发图片选择demo

点击demo页面这个蓝色按钮:

点击蓝色按钮

选择自己电脑中对应的图片,例如我选择了2张不错的PNG图片:

选择图像截图示意

结果在Web页面上成功预览了图片效果,如下截图所示:

页面上预览效果示意

是不是跟传统的file文件选择很类似。

由于这些全新的API都是走的Promise,因此,可以使用async、 await等新的JS语法,避免各种乱糟糟的回调,代码更简洁更易读了。

是不是很赞!

四、可惜是个新API
对于不喜欢HTML表单元素,喜欢JavaScript代码一把梭的开发者而言,这个API会很亲近很喜欢,但是,遗憾的是,这个API出来的比较新,去年下半年才出来,Safari浏览器并不支持,因此,不能直接使用。

兼容性

不过,有不少项目做了mix混合处理,也就是写了个 JS,支持的浏览器使用 File System Access API,不支持的浏览器还是使用传统的 ,例如谷歌实验室的这个项目 browser-fs-access

如果是文件保存或下载,则可以试试window.showSaveFilePicker()这个 API,有时候可以介绍下,当然,实际开发,文件下载肯定是使用 FileSaver.js,这可以文件下载当仁不让的王者,标杆项目。

其他限制
需要https环境,如果是本地localhost 不受此限制。
不能在 iframe 内使用,因为被认为不安全

114之前版本下载链接在这里
https://chromedriver.chromium.org/downloads

​​​​​​126以后版本下载链接在此,只有后面status是绿色对勾的才可以下载,驱动大版本一致就可以使用,不需版本号一模一样;下载所需版本只需点击对应的版本名称即可跳转到对应版本的下载位置。

https://googlechromelabs.github.io/chrome-for-testing/#stable

如果找不到对应的版本的比如最新的是127的,要找126的页面上没有,就把下载URL中的版本号替换成目标版本试试能不能下载:

#比如 127.0.6533.119 替换成 我想要下载的 126.0.6478.127 
https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/win64/chromedriver-win64.zip

lsof命令是什么?

可以列出被进程所打开的文件的信息。被打开的文件可以是

1.普通的文件,2.目录 3.网络文件系统的文件,4.字符设备文件 5.(函数)共享库 6.管道,命名管道 7.符号链接

8.底层的socket字流,网络socket,unix域名socket

9.在linux里面,大部分的东西都是被当做文件的…..还有其他很多

怎样使用lsof

这里主要用案例的形式来介绍lsof 命令的使用

1.列出所有打开的文件:

lsof

备注: 如果不加任何参数,就会打开所有被打开的文件,建议加上一下参数来具体定位

  1. 查看谁正在使用某个文件

lsof /filepath/file

3.递归查看某个目录的文件信息

lsof +D /filepath/filepath2/

备注: 使用了+D,对应目录下的所有子目录和文件都会被列出

  1. 比使用+D选项,遍历查看某个目录的所有文件信息 的方法

lsof | grep ‘/filepath/filepath2/’

  1. 列出某个用户打开的文件信息

lsof -u username

备注: -u 选项,u其实是user的缩写

  1. 列出某个程序所打开的文件信息

lsof -c mysql

备注: -c 选项将会列出所有以mysql开头的程序的文件,其实你也可以写成 lsof | grep mysql, 但是第一种方法明显比第二种方法要少打几个字符了

  1. 列出多个程序多打开的文件信息

lsof -c mysql -c apache

  1. 列出某个用户以及某个程序所打开的文件信息

lsof -u test -c mysql

  1. 列出除了某个用户外的被打开的文件信息

lsof -u ^root

备注:^这个符号在用户名之前,将会把是root用户打开的进程不让显示

  1. 通过某个进程号显示该进行打开的文件

lsof -p 1

  1. 列出多个进程号对应的文件信息

lsof -p 123,456,789

  1. 列出除了某个进程号,其他进程号所打开的文件信息

lsof -p ^1

13 . 列出所有的网络连接

lsof -i

  1. 列出所有tcp 网络连接信息

lsof -i tcp

  1. 列出所有udp网络连接信息

lsof -i udp

  1. 列出谁在使用某个端口

lsof -i :3306

  1. 列出谁在使用某个特定的udp端口

lsof -i udp:55

特定的tcp端口

lsof -i tcp:80

  1. 列出某个用户的所有活跃的网络端口

lsof -a -u test -i

  1. 列出所有网络文件系统

lsof -N

20.域名socket文件

lsof -u

21.某个用户组所打开的文件信息

lsof -g 5555

  1. 根据文件描述列出对应的文件信息

lsof -d description(like 2)

  1. 根据文件描述范围列出文件信息

lsof -d 2-3