我在学习 chrome 插件开发的过程中遇到一个问题,代码如下:
(function(){
var protocol = window.location.protocol;
var host = window.location.host;
var href = window.location.href;
var source = document.getElementsByTagName('html')[0].innerHTML;
var target_list = [];
var js_result = [];
var source_href = source.match(/href=['"].*?['"]/g);
var source_src = source.match(/src=['"].*?['"]/g);
var script_src = source.match(/<script [^><]*?src=['"].*?['"]/g);
if(source_href){
for(var i=0;i<source_href.length;i++){
var u = deal_url(source_href[i].substring(6,source_href[i].length-1));
if(u){
target_list.push(u);
}
}
}
if(source_src){
//var js_result = [];
for(var i=0;i<source_src.length;i++){
var u = deal_url(source_src[i].substring(5,source_src[i].length-1));
if(u){
target_list.push(u);
var xhr = new XMLHttpRequest();
xhr.open("GET", u, true);
xhr.send();
xhr.onreadystatechange = function() {
var src = this.responseText;
var script_url = src.match(/( https?|http|ftp|file):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/g);
if(script_url){
for(var t=0;t<script_url.length;t++){
var y = script_url[t];
if(y){
js_result.push(y);
}
}
}
}
}
}
}
console.log(js_result)
console.log(target_list)
问题是: console 打印出来的 js_result 和 target_list 是不同形式的(就好像一个数组是空的,一个数组包含了值), 如图:
点开空的那个▶️, 就能看到结果,但是没有直接显示出来
1
RaDisH7 2023-04-29 15:20:58 +08:00 1
因为你的 xhr 请求是异步的,可以去了解一下 JavaScript 的异步、同步、promise 这些东西 https://zh.javascript.info/async
|
3
fu4k OP 感觉 promise 、await 、async 理解起来好难🤯
|
4
fu4k OP 有没有好心人能给出 code 示例🙏
|
5
turan12 2023-04-29 19:46:57 +08:00
xhr.open("GET", u, true) 改为 xhr.open("GET", u, false) ,就创建了一个同步请求
|
6
huijiewei 2023-04-29 19:52:38 +08:00
@fu4k 很好理解啊。异步就是数据只能在 callback 里面取到,promise 就是承诺给你数据,要在 then 里面处理,async/await 就是异步转为同步代码
|
9
Yukiteru 2023-04-29 21:15:06 +08:00
可以用 fetch 啊,然后 await
|
10
huijiewei 2023-04-29 21:15:52 +08:00
@fu4k 付什么费。js_result 只有在 xhr.onreadystatechange 的方法里面才是真正的数据
|
11
huijiewei 2023-04-29 21:16:41 +08:00
onreadystatechange 就是 xhr 的一个 callback 。
|
12
stefanieewu 2023-04-29 21:31:02 +08:00
如果你不想改现在代码结构的话,就在 xhr 的回调里面判断拿到了多少条请求结束的结果,然后判断长度是不是超过了 soucre_src 数组的长度,如果超过,说明所有发出的请求都结束了(不管成功失败)这时候打印
if (source_src) { //var js_result = []; let index = 0; let callbackFun = () => { console.log(js_result) console.log(target_list) } // ...其他代码 xhr.onreadystatechange = () => { // 最后新加 index++; if (index >= source_src.length) { // 执行所有请求结束的回调 // callback() callbackFun() } } } 当然是建议用 promise + promise.all 去写,或者用 fetch ; 如果有其他问题,可以加我 vx:bGlqaWF0dTE5OTg= |
14
lneoi 2023-04-29 22:46:22 +08:00
没看太懂问题是什么。
console 打印对象时也是引用的,打印语句执行的时候对象是空的,所以预览信息里面就是空的。当点开后会去读取最新的内容,刚好你这变量异步请求后会更新值,所以点开后会后跟预览不一样的信息。 |
16
7gugu 2023-04-30 18:17:47 +08:00
直接在对应的位置输入“debug”,直接打断点就能看到对应的变量值了
|