正常来说iframe现在是不能正常获取微信公众号的图片的(设置了响应头“frame-ancestores:self”,所以导致在iframe中不能打开),但是可以通过代理来绕过微信的验证,这里暂时先使用http://cors-anywhere.herokuapp.com/corsdemo来进行处理。

        备注:cors-anywhere早在2021年1月31日就已经停止作为开放代理,由于被很多人滥用,并且越来越频繁,所以导致现在请求会返回403(拒绝访问)状态,但是目前可以通过访问网址申请访问权限

2022.11.4修改:corsdemo不能访问了,本文作废,现在仅供参考

2022.11.15更新:忘记说明了,可以本地从git上下载这个cors-anywhere然后通过node.js命令(npm install + node server.js)自己做代理就可以正常访问了,然后如果发布到公网,需要在服务器上运行这个服务(本质上来说cors-anywhere的实现就是后端通过伪造成微信同源发送获取文章的内容,返回给前端)

实现的代码如下:

<iframe src="" frameborder="0" id="iFrame" width="100%" scrolling="no" :height="height"></iframe>

js:

let URL = "https://mp.weixin.qq.com/s/oGfjG6TUvJc9PMI-PzxOAA";
//微信的文章地址
//调用跨域API
let realurl = 'https://cors-anywhere.herokuapp.com/' + URL;
let that = this;
$.ajax({
    type: 'get',
    url: realurl,
    success: function (response) {
        if (response) {
            let html = response;
            html = html.replace(/data-src/g, "src")
                .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/g, '')
                .replace(/https/g, 'http');
            //根据微信传回的html中的特殊路径data-src转为src等
            let html_src = html;
            let iframe = document.getElementById('iFrame');
            iframe.src = html_src;
            //这时候就成功拿到了微信公众号,这个html_src是个静态网页
            let doc = iframe.contentDocument || iframe.document;
            doc.write(html_src);
            // 将静态页面写入iframe中
            setTimeout(() => {
                that.height = doc.documentElement.scrollHeight;
            }, 500);
            //通过延时获取文档高度赋值Iframe去除滚动条,根据实际情况增加延时时间
            doc.getElementById("js_content").style.visibility = "visible";
        }
    },
    error: function (err) {
        console.log(err);
    }
})

 以上代码写完后页面上的iframe应该正常展示了文章,但是!!!没有图片,因为图片的src也被拦截了,但是也可以处理:对iframe的head处理

......
let doc = iframe.contentDocument || iframe.document;
let head = doc.querySelector("head");
let meta = `<meta name="referrer" content="never">`;
head.innerHTML += meta;
.......
doc.write(html_src);

这时候图片img应该是正常展示的:

但是又有状况:有的文章是图片作为背景图片的,这个没办法看:

 这时候就到了最关键的时候了:

......
let backgroundUrlReg = /url[(]&quot;(\S*)&quot;/g;
let backgroundImgs = html_src.match(backgroundUrlReg);
//通过正则对获取到的静态页面进行过滤拿到所有背景图片的url
//本人的正则不是很熟练,大佬可以自行对正则优化,这里只是提供一个思路
if (backgroundImgs.length) {
    backgroundImgs.forEach(item => {
        let url = item.replace(/url[(]&quot;/g, '').replace(/&quot;/g, '');
        let img = document.createElement('img');
        img.src = url;
        doc.querySelector("body").appendChild(img);
        //通过对生成一个无效的img进行赋值,使这个路径能够绕过检测,这样背景图片也能够正常展示了
    });
}
......
doc.write(html_src);

 以下就是最终的效果:

 这样就成功的在iframe成功访问了微信公众号的文章

贴上最终的整合代码:

<iframe src="" frameborder="0" id="iFrame" width="100%" scrolling="no" :height="height"></iframe>

js:

let URL = "https://mp.weixin.qq.com/s/oGfjG6TUvJc9PMI-PzxOAA";
//微信的文章地址
//调用跨域API
let realurl = 'https://cors-anywhere.herokuapp.com/' + URL;
let that = this;
$.ajax({
    type: 'get',
    url: realurl,
    success: function (response) {
        if (response) {
            let html = response;
            html = html.replace(/data-src/g, "src")
                .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/g, '')
                .replace(/https/g, 'http');
            //根据微信传回的html中的特殊路径data-src转为src等
            let html_src = html;
            let iframe = document.getElementById('iFrame');
            iframe.src = html_src;
            //这时候就成功拿到了微信公众号,这个html_src是个静态网页
            let doc = iframe.contentDocument || iframe.document;

            let head = doc.querySelector("head");
            let meta = `<meta name="referrer" content="never">`;
            head.innerHTML += meta;
            //添加meta展示图片

            let backgroundUrlReg = /url[(]&quot;(\S*)&quot;/g;
            let backgroundImgs = html_src.match(backgroundUrlReg);
            if (backgroundImgs.length) {
                 backgroundImgs.forEach(item => {
                    let url = item.replace(/url[(]&quot;/g, '').replace(/&quot;/g, '');
                    let img = document.createElement('img');
                    img.src = url;
                    doc.querySelector("body").appendChild(img);
                });
            }
            //配置无效img绕过背景图片路径限制

            doc.write(html_src);
            // 将静态页面写入iframe中
            setTimeout(() => {
                that.height = doc.documentElement.scrollHeight;
            }, 500);
            //通过延时获取文档高度赋值Iframe去除滚动条,根据实际情况增加延时时间
            doc.getElementById("js_content").style.visibility = "visible";
        }
    },
    error: function (err) {
        console.log(err);
    }
})

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐