async function 运行js代码并上传文件(e) {
let { tabId: t, jsdm: h ,files:g } = e;
var n={tabId: t};
let a= await chrome.debugger.attach(n, "1.3");
a= await chrome.debugger.sendCommand(n, "Runtime.evaluate", {expression: h});//运行js代码并返回objectId
let objectId=a.result.objectId; //获取元素文件框的objectId
await chrome.debugger.sendCommand(n, "DOM.setFileInputFiles", { objectId:objectId, files: g}) //上传文件路径
}
js代码格式如下:
var gg=window.frames[1]; //切换到指定框架,从顶层框架里查找frames的位置,并切换到frame框架里面
gg.document.querySelector('#textInput').value=123; //指定框架运行的js代码
gg.aa=[1,2,3,4,5]; //向框架中声明全局变量aa
gg.document.querySelector('#fileInput'); //获取框架中元素文件框的objectId,一定要放到最后一行,为上传文件准备
最后一行一定要为文件框元素,例如:gg.document.querySelector('#fileInput'),这样就可以获取到获取元素文件框的objectId,不要写属性
注意:使用Runtime.evaluate直接在js代码上切换到指定框架【window.frames[1]】,获取框架中元素文件框的objectId【gg.document.querySelector('#fileInput'); 】 这一步很关键!!!
//参数说明
tabId: 调试目标
jsdm: js代码
files: 需要上传文件的路径数组
//参数示例
{
tabId: 779853286,
jsdm: `var gg=window.frames[1];
gg.document.querySelector('#textInput').value=123;
gg.aa=[1,5,9,833,5];
gg.document.querySelector('#fileInput');`,
files: ["C:/Users/Administrator/Desktop/11.png"]
}
注意:mv3版本地的网页可能不能使用(file:///开头的,可能是本地域不同造成的,Runtime.evaluate里面的限制)
以下是两个子程序可以测试:
https://getquicker.net/subprogram?id=3aa0bc73-e66b-48a7-8c78-08dda3deac8a(mv3版)
https://getquicker.net/subprogram?id=e60c459d-62a0-4792-8c88-08dda3deac8a(mv2版)
可以先用js声明一个函数,再指定是哪一个 iframe框架,再调用 如下:
function 指定框架(e) {
let g= window.frames[e];
g.document.querySelector('#textInput').value=123;
g.aa=[1,5,9,833,5];
let d=g.document.querySelector('#fileInput');
return d
}
原理顺序:
一.连接tabId
chrome.debugger.attach({ tabId: tabId }, '1.3', () => {console.log('连接');})
二.Runtime.evaluate 运行js代码并获取元素文件框的objectId,为上传文件准备
chrome.debugger.sendCommand(
{ tabId: tabId }, 'Runtime.evaluate', {expression:
`var gg=window.frames[1];
gg.document.querySelector('#textInput').value=123;
gg.aa=[1,2,3,5,4];
gg.document.querySelector('#fileInput');`
}, function(response) {console.log(response.result.objectId);});
result格式如下:
{
"className": "HTMLInputElement",
"description": "input#fileInput",
"objectId": "-2475387284660854303.1.1",
"subtype": "node",
"type": "object"
}
三.DOM.setFileInputFiles 上传文件路径
chrome.debugger.sendCommand({tabId: tabId}, "DOM.setFileInputFiles", {"objectId": "-2475387284660854303.1.1","files":["C:/Users/Administrator/Desktop/11.png"]})
下面是一些原理过程,可以相互推导,目的不同,需要用的数据不同
目的是为了获取iframe框架的上下文ID 转了一圈,可以相互推导求值 iframe框架上下文ID是变化的,网页刷新、表单提交等 iframe框架上下文ID也会跟着变化
1.Runtime.evaluate 这是顶层框架 顶层框架上下文ID,也就是默认的,可以省略,理论上开始的上下文ID,默认是1 网页刷新、表单提交等上下文ID会跟着变化
chrome.debugger.sendCommand({ tabId: tabId }, 'Runtime.evaluate', {expression:
`var gg=window.frames[1];
gg.document.querySelector('#textInput').value=123;
gg.aa=[1,2,3,5,4];
gg.document.querySelector('#fileInput');`}, function(response) {console.log( response.result.objectId );});
result格式如下:
{
"className": "HTMLInputElement",
"description": "input#fileInput",
"objectId": "4489587955195509192.14.8", // 顶层框架上下文ID【14】,也就是默认的,可以省略
"subtype": "node",
"type": "object"
}
2.DOM.describeNode 获取iframe框架的backendNodeId
chrome.debugger.sendCommand({tabId: tabId}, 'DOM.describeNode',{ objectId :'4489587955195509192.14.8' },(result) => {console.log( result.node.backendNodeId );})
node格式如下:
{
"attributes": [
"type",
"file",
"id",
"fileInput",
"name",
"fileInput"
],
"backendNodeId": 1112,
"childNodeCount": 0,
"localName": "input",
"nodeId": 0,
"nodeName": "INPUT",
"nodeType": 1,
"nodeValue": "",
"shadowRoots": [
{
"backendNodeId": 1116,
"childNodeCount": 2,
"localName": "",
"nodeId": 0,
"nodeName": "#document-fragment",
"nodeType": 11,
"nodeValue": "",
"shadowRootType": "user-agent"
}
]
}
3.DOM.resolveNode 获取iframe框架的objectId
chrome.debugger.sendCommand({tabId: tabId}, 'DOM.resolveNode',{ backendNodeId:1112 },(result) => {console.log( result.object.objectId );})
object格式如下:
{
"className": "HTMLInputElement",
"description": "input#fileInput",
"objectId": "4489587955195509192.46.1", iframe框架上下文ID【46】
"subtype": "node",
"type": "object"
}
4.Runtime.evaluate 通过iframe框架的上下文ID,运行js代码
chrome.debugger.sendCommand({tabId: tabId}, 'Runtime.evaluate', {expression:'var ss=[1,2,3,4];',contextId : 46 })
强烈建议来这里发一遍 https://getquicker.net/KC/Kb/New
嗯嗯,这样东西有些乱,它们互相关联,需要一个明确的目的,才能将其串联起来,单独来发,不知道怎样发