记录前端菜鸟的日常——微信公众号文章在H5的显示

今天有这样一个需求,PC端新加一个第三方链接的字段,H5需要将第三方链接展示出来(之后再在小程序上展示)

最开始我配好的链接就直接拿去显示了,它会显示这个图标:

查了一下说是微信官方拒绝非同域网站用iframe将其嵌套,于是根据这个大佬的文章最后解决了这个问题:https://blog.csdn.net/weixin_46027556/article/details/146006993?ops_request_misc=&request_id=&biz_id=102&utm_term=%E5%9C%A8iframe%E4%B8%AD%E5%B5%8C%E5%85%A5%E5%BE%AE%E4%BF%A1%E5%85%AC%E4%BC%97%E5%8F%B7%E6%96%87&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-146006993.142^v102^pc_search_result_base4&spm=1018.2226.3001.4187

一、nginx配置

nginx配置用于解决前端项目访问微信域名时的跨域问题,并实现请求转发

将所有以wx代理到mp.weixin.qq.com(公众号链接的开头)

以wxImg开头的代理到https://mmbiz.qpic.cn(公众号里图片的链接开头)

proxy_pass就是将请求头转发到微信服务器

 location /wx/ {
      add_header 'Access-Control-Allow-Origin' '*';
      add_header 'Access-Control-Allow-Headers' '*';
      add_header 'Access-Control-Allow-Methods' '*';
      proxy_pass https://mp.weixin.qq.com/;
}

location /wxImg/ {
     add_header 'Access-Control-Allow-Origin' '*';
     add_header 'Access-Control-Allow-Headers' '*';
     add_header 'Access-Control-Allow-Methods' '*';
     proxy_pass https://mmbiz.qpic.cn/;
}

二、前端配置

我们使用的是Vue2

先在data里配置这些:

这里的proxy写你后端请求的那个地址,图片的话我记得好像是有这两种开头的所以就写了两种

proxy: 'https://xxxxxxxxx.cn/',
      mapper: {
        'https://mp.weixin.qq.com': 'toinfo',
        'http://mp.weixin.qq.com': 'toinfo',
        'https://mmbiz.qpic.cn': 'wxImg',
        'http://mmbiz.qpic.cn': 'wxImg',
        'https://mmecoa.qpic.cn': 'wxmmecoa',
        'http://mmecoa.qpic.cn': 'wxmmecoa',
      }

这样写当你请求https://mp.weixin.qq.com/article 的时候它就给你代理去请求到https://xxxxxxxxxx/toinfo/article

然后写两个方法:

proxyUrl(url) {
      for (const key in this.mapper) {
        if (url.startsWith(key)) {
          return this.proxy + this.mapper[key] + url.slice(key.length)
        }
      }
      console.log(url, 'url')
      return url
    },
    async iframeLoadWxmp(url) {
      try {
        const iframe = this.$refs.wxIframe
        // console.log(iframe,'iframe')
        if (!iframe) return

        // 使用fetch替代jQuery.ajax
        const response = await fetch(this.proxyUrl(url))
        console.log(response, 'response')
        let html = await response.text()

        // 替换处理逻辑
        html = html
          .replace(/data-src="(http[^"]+)"/g, (_, g) => `src="${this.proxyUrl(g)}"`)
          .replace(/background-image: url\("(http[^&]+)/g, (_, g) =>
            `background-image: url(${this.proxyUrl(g)}`)
          .replace(/<meta\s+name="referrer"\s+content="[^"]+"/g,
            '<meta name="referrer" content="never"')

        const doc = iframe.contentDocument || iframe.contentWindow.document

        // 处理背景图片
        const bgUrlReg = /url\(['"]?([^'")]+)['"]?\)/g
        let bgMatches
        while ((bgMatches = bgUrlReg.exec(html)) !== null) {
          const imgUrl = bgMatches[1]
          const img = document.createElement('img')
          img.src = imgUrl
          doc.body.appendChild(img)
        }

        doc.open()
        doc.write(html)
        doc.close()
      } catch (error) {
        console.error('加载失败:', error)
      }
    }
<iframe v-if="urlFlag" ref="wxIframe" style="width: 100vw; height: 100vh;"></iframe>

第一个方法是遍历、匹配、替换,拿到代理后的地址,已经拿到了主地址

第二个方法是处理一些嵌套的资源,图片之类的就不详细看了

iframe标签这里高度我写了100%之后还是那么一小条,然后我才想起来vh、vw这个单位,用这个就ok了

完事之后就在mounted里调用就可以了

this.$nextTick(() => {
        setTimeout(() => {
          this.iframeLoadWxmp(this.$route.query.thirdPartyUrl);
        }, 100); // 适当延迟
      });

本来是直接调用函数的,结果展示出来永远是一片白,本来以为是我哪里配置的不对,找半天发现是一开始就调用函数还没拿到iframe的实例,加个延迟就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值