收藏
回答

onShareAppMessage 分享链接无法现实图片?

实现方式

1:

## 问题标题
小程序拼单分享 `onShareAppMessage` 已返回 `imageUrl`,但聊天卡片仍灰色占位(体验版)


## 业务场景
拼单分享页点击“分享”按钮,分享给微信好友。  
目标:卡片显示自定义标题 + 商品封面图。


---


## 代码实现(可直接复现)


### 1)拼单列表页分享入口  
文件:`pages/sharebill/sharebillList/sharebillList.js`


const {
  buildShareAppMessageWithLocalImage,
  SHARE_FALLBACK_IMAGE_URL,
  pushShareDebugLog
} = require('../../../utils/shareCover.js');
const { getStaticFileBaseForRelativePath } = require('../../../utils/staticFileBase.js');


Page({
  onShareButtonTap(e) {
    const dataset = e.currentTarget.dataset;
    const orderId = dataset.orderId;
    const shareBillNumber = dataset.shareBillNumber || '';
    const productImage = dataset.productImage || '';
    if (orderId) {
      this.setData({
        sharingMode: 'sharebill',
        sharingOrderId: orderId,
        sharingShareBillNumber: shareBillNumber,
        sharingImageUrl: productImage
      });
    }
  },


  onShareAppMessage(options) {
    let mode = this.data.sharingMode || 'sharebill';
    let productImageRaw = this.data.sharingImageUrl || '';
    let orderId = this.data.sharingOrderId;
    let shareBillNumber = this.data.sharingShareBillNumber || '';
    let productId = this.data.sharingGroupProductId || '';
    let groupId = this.data.sharingGroupId || '';


    // open-type="share" 走 button 时,优先从 options.target.dataset 取值
    if (options && options.from === 'button' && options.target) {
      const d = options.target.dataset || {};
      const pid = d.productId;
      const gid = d.groupId;
      if (pid != null && pid !== '' && gid != null && gid !== '') {
        mode = 'groupbuy';
        productId = pid;
        groupId = gid;
        productImageRaw = d.productImage != null ? d.productImage : '';
      } else if (d.orderId != null && d.orderId !== '') {
        mode = 'sharebill';
        orderId = d.orderId;
        shareBillNumber = d.shareBillNumber != null ? d.shareBillNumber : '';
        productImageRaw = d.productImage != null ? d.productImage : '';
      }
    }


    const imageUrl = this.resolveShareImageUrl(productImageRaw || '');
    pushShareDebugLog('sharebill.list.onShareAppMessage', {
      from: options && options.from ? options.from : '',
      mode,
      orderId: orderId != null ? String(orderId) : '',
      shareBillNumber: shareBillNumber || '',
      productId: productId != null ? String(productId) : '',
      groupId: groupId != null ? String(groupId) : '',
      productImageRaw: productImageRaw || '',
      resolvedImageUrl: imageUrl
    });


    if (mode === 'groupbuy') {
      const sharePath = `/pages/goods/goods?id=${encodeURIComponent(String(productId))}&groupId=${encodeURIComponent(String(groupId))}`;
      return buildShareAppMessageWithLocalImage({
        title: '拼团邀请就差你了',
        path: sharePath,
        imageUrl
      });
    }


    const sharePath = `/pages/sharebill/sharebillDetail/sharebillDetail?shareType=shareBillType&share_bill_number=${shareBillNumber}&order_id=${orderId != null ? orderId : ''}`;
    return buildShareAppMessageWithLocalImage({
      title: '拼单返现就差你了',
      path: sharePath,
      imageUrl
    });
  },


  resolveShareImageUrl(url) {
    let u = url && typeof url === 'string' ? url.trim() : '';
    if (/^\/\//.test(u)) u = `https:${u}`;
    if (u && /^https?:\/\//i.test(u)) return u;


    const site = getStaticFileBaseForRelativePath(u);
    if (u && site) {
      const normalizedSite = site.endsWith('/') ? site.slice(0, -1) : site;
      const normalizedPath = u.startsWith('/') ? u : `/${u}`;
      return `${normalizedSite}${normalizedPath}`;
    }
    return SHARE_FALLBACK_IMAGE_URL;
  }
});


2:分享工具方法

文件:utils/shareCover.js

const SHARE_FALLBACK_IMAGE_URL =
  'https://ling.sanjuhealth.com/system_imge/4e9c5ba6-315d-4259-9a2d-d1b7df8bc457.png';
const SHARE_DEBUG_KEY = '__share_debug_logs__';
const SHARE_USE_PROMISE_IMAGE_FLOW = false;


function pushShareDebugLog(stage, payload) {
  const row = { ts: new Date().toISOString(), stage, payload: payload || {} };
  console.log('[share-debug]', row);
  try {
    const old = wx.getStorageSync(SHARE_DEBUG_KEY);
    const list = Array.isArray(old) ? old : [];
    list.push(row);
    while (list.length > 80) list.shift();
    wx.setStorageSync(SHARE_DEBUG_KEY, list);
  } catch (e) {}
}


function coerceImageUrlForShareCard(url) {
  if (!url || typeof url !== 'string') return SHARE_FALLBACK_IMAGE_URL;
  const t = url.trim();
  if (!t) return SHARE_FALLBACK_IMAGE_URL;
  if (/\.webp(\?|#|$)/i.test(t)) return SHARE_FALLBACK_IMAGE_URL;
  return t;
}


function buildShareAppMessageWithLocalImage(payload) {
  const title = payload.title || '活龄小程序';
  const path = payload.path || '/pages/main/main';
  const imageUrl = coerceImageUrlForShareCard(payload.imageUrl);
  pushShareDebugLog('share.appmessage.payload', { title, path, imageUrl });


  // 兼容优先:同步返回 object(不走 promise + tempFile)
  if (!SHARE_USE_PROMISE_IMAGE_FLOW) {
    return { title, path, imageUrl };
  }


  // 备选:promise 流(目前已关闭)
  return {
    title,
    path,
    imageUrl
  };
}


module.exports = {
  SHARE_FALLBACK_IMAGE_URL,
  SHARE_DEBUG_KEY,
  pushShareDebugLog,
  buildShareAppMessageWithLocalImage
};

3:全局包装(Page 重写)

文件:app.js

const ENABLE_SHARE_LOGIN_TIP = true;
const originalPage = Page;


Page = function(options) {
  const getCurrentUserId = function() {
    try {
      const userInfoStr = wx.getStorageSync('userInfo');
      if (userInfoStr) {
        const userInfo = typeof userInfoStr === 'string' ? JSON.parse(userInfoStr) : userInfoStr;
        return userInfo.id || userInfo.userId || null;
      }
    } catch (e) {}
    return null;
  };


  const processSharePath = function(path) {
    if (!path) return path;
    const referrerId = getCurrentUserId();
    if (!referrerId) return path;
    if (path.includes('referrer_id=')) return path;
    const separator = path.includes('?') ? '&' : '?';
    return `${path}${separator}referrer_id=${referrerId}`;
  };


  const maybeShowShareLoginTip = function(shareConfig) {
    if (!ENABLE_SHARE_LOGIN_TIP) return shareConfig;
    if (getCurrentUserId()) return shareConfig;
    return new Promise(function(resolve, reject) {
      wx.showModal({
        title: '提示',
        content: '您还未登录,分享链接将不携带您的邀请人ID,新用户将无法成为您的下级。',
        confirmText: '分享',
        cancelText: '去登录',
        success: function(res) {
          if (res.confirm) resolve(shareConfig);
          else {
            wx.navigateTo({ url: '/pages/login/login' });
            reject();
          }
        }
      });
    });
  };


  const applyShareAppMessageWrap = function(shareConfig) {
    if (!shareConfig || typeof shareConfig !== 'object') {
      return maybeShowShareLoginTip(shareConfig);
    }
    if (shareConfig.path) {
      shareConfig.path = processSharePath(shareConfig.path);
    }
    return maybeShowShareLoginTip(shareConfig);
  };


  if (options.onShareAppMessage) {
    const originalOnShareAppMessage = options.onShareAppMessage;
    options.onShareAppMessage = function(shareOptions) {
      const raw = originalOnShareAppMessage.call(this, shareOptions);
      if (raw && typeof raw.then === 'function') {
        return raw.then(applyShareAppMessageWrap);
      }
      return applyShareAppMessageWrap(raw);
    };
  }


  return originalPage(options);
};

日志

[share-debug] stage: sharebill.list.onShareAppMessage
payload:
  from: "button"
  mode: "sharebill"
  orderId: "63"
  shareBillNumber: "SB1776..."
  productImageRaw: "https://ling.sanjuhealth.com/product_img/5fefe53f-1c0c-4963-8fe0-92423c9435b5.png"
  resolvedImageUrl: "https://ling.sanjuhealth.com/product_img/5fefe53f-1c0c-4963-8fe0-92423c9435b5.png"


[share-debug] stage: share.appmessage.payload
payload:
  title: "拼单返现就差你了"
  path: "/pages/sharebill/sharebillDetail/sharebillDetail?shareType=shareBillType&share_bill_number=SB1776...&order_id=63"
  imageUrl: "https://ling.sanjuhealth.com/product_img/5fefe53f-1c0c-4963-8fe0-92423c9435b5.png"



体验版还是正式版都无法现实

只有分享端(分享人用手机分享然后再被分享人的聊天记录中可以看到图片,但是被分享人自己的微信中是看不到图片的,并且分享人如果去PC端也是看不到图片的)


最后一次编辑于  04-29
回答关注问题邀请回答
收藏

2 个回答

  • 社区技术运营专员--阳光
    社区技术运营专员--阳光
    04-20

    没复现 有稳定复现的方式吗 是只有你有问题还是其他人都可复现

    04-20
    有用
    回复 5
    • 沐千熏
      沐千熏
      04-22
      有,分享是无法显示图片是用onShareAppMessage 函数进行分享某个其他页面,并且将商品图片作为imageUrl 进行展示的分享。首页使用三个点中的分享,是在正式版上被分享者是可以看到展示图片的。
      04-22
      回复
    • 沐千熏
      沐千熏
      04-22
      然后就是你这个了,我这边确认问一下是你分享的并且是在你自己的微信上看的吗?如果是这个你自己分享,然后去自己的聊天记录中看是可以看到图的,但是在被分享者的微信上是没有图片的
      04-22
      回复
    • 沐千熏
      沐千熏
      04-22
      也就是我说的这种情况
      04-22
      回复
    • 沐千熏
      沐千熏
      1天前
      还在吗?
      1天前
      回复
    • 沐千熏
      沐千熏
      11小时前
      这个问题不能解决吗?
      11小时前
      回复
  • 智能回答 智能回答 本次回答由AI生成
    04-17
    有用
    回复 2
    • 沐千熏
      沐千熏
      04-17
      request合法域名中也有配置
      AppID:wx3473d28075d29ae1
      04-17
      回复
    • 沐千熏
      沐千熏
      04-17
      已按文档实现并验证,仍复现:


      1)onShareAppMessage 返回值(分享者端日志):
      title: 拼单返现就差你了
      path: /pages/sharebill/sharebillDetail/sharebillDetail?shareType=...&order_id=63
      imageUrl: https://ling.sanjuhealth.com/product_img/xxxx.png


      2)图片可公网访问:
      - HTTPS
      - Content-Type: image/png
      - HTTP 200


      3)小程序后台域名已配置:
      - request/downloadFile 均包含 https://ling.sanjuhealth.com
      - 其他相关域名也已配置


      4)被分享者可正常打开 path,对应详情接口返回 productImage 也是同一 URL。


      问题是:仅聊天卡片封面灰色占位,不显示 imageUrl。
      请协助确认:
      - 体验版是否存在对 onShareAppMessage imageUrl 的平台侧策略限制?
      - 是否有客户端版本已知问题?
      - 该场景是否需要除 request/downloadFile 之外的额外配置?
      04-17
      回复
登录 后发表内容