You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js/React应用中动态Open Graph元标签的组件实现及爬虫抓取问题求助

Next.js/React应用中动态Open Graph元标签的组件实现及爬虫抓取问题求助

我最近在Next.js/React项目里碰到了一个头疼的问题:动态生成的Open Graph(OG)元标签,在Chrome的Elements面板里明明能看到,但LinkedIn帖子检查器和Facebook调试工具就是抓不到。看Network面板的Response内容,里面根本没有这些OG标签,爬虫自然也就识别不了。

下面是我当前的代码实现,麻烦帮我看看哪里出问题了:

页面组件:src/pages/share-property/index.tsx

import React from "react";
import Property from "components/Sharing/Property";
import { GetServerSideProps } from "next";
import { Buffer } from 'buffer';
import { NextPage } from 'next';
import Head from 'next/head';

// Import Head
interface PropertyData {
  companyName: string;
  tenantId: string;
  stage: string;
  firstName: string;
  imageUrl: string;
  headerText?: string;
  resolvedImageUrl: string;
  fullUrl: string;
}

interface Props {
  propertyData: PropertyData | null;
}

const IndexPage: NextPage<Props> = ({ propertyData }) => {
  const shareTitle = propertyData ? `${propertyData.companyName} - ${propertyData.headerText}` : 'Loading...';
  const shareDescription = propertyData ? `Check out this property update from ${propertyData.companyName}` : '';

  return (
    <>
      <Head>
        {/* Primary Meta Tags */}
        <title>{shareTitle}</title>
        <meta name="description" content={shareDescription} />
        <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />

        {propertyData && (
          <>
            {/* Open Graph / Facebook */}
            <meta property="og:title" content={shareTitle} />
            <meta property="og:description" content={shareDescription} />
            <meta property="og:image" content={propertyData.resolvedImageUrl} />
            <meta property="og:url" content={propertyData.fullUrl} />
            <meta property="og:type" content="website" />
            <meta property="og:image:width" content="1200" />
            <meta property="og:image:height" content="630" />
            <meta property="og:image:alt" content={`Property image from ${propertyData.companyName}`} />
            <meta property="og:site_name" content={propertyData.companyName} />

            {/* Twitter */}
            <meta name="twitter:card" content="summary_large_image" />
            <meta name="twitter:title" content={shareTitle} />
            <meta name="twitter:description" content={shareDescription} />
            <meta name="twitter:image" content={propertyData.resolvedImageUrl} />
          </>
        )}
      </Head>

      {propertyData ? (
        <Property
          companyName={propertyData.companyName}
          tenantId={propertyData.tenantId}
          stage={propertyData.stage}
          firstName={propertyData.firstName}
          imageUrl={propertyData.imageUrl}
          headerText={propertyData.headerText}
          resolvedImageUrl={propertyData.resolvedImageUrl}
          fullUrl={propertyData.fullUrl}
        />
      ) : (
        <div>Loading property data...</div>
      )}
    </>
  );
};

export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
  const { query, req } = context;
  const data = query.data as string;

  console.log("getServerSideProps is running");

  if (!data) {
    console.log("No data query parameter");
    return {
      props: { propertyData: null },
    };
  }

  try {
    const decodedData = JSON.parse(Buffer.from(data, 'base64').toString('utf-8'));
    const {
      companyName,
      stage,
      imageUrl,
      firstName = "",
      tenantId = "",
      headerText = "Property Update"
    } = decodedData;

    const origin = req ? `${req.headers['x-forwarded-proto'] || 'http'}://${req.headers.host}` : '';
    const fullUrl = `${origin}${context.resolvedUrl}`;

    const getAbsoluteImageUrlServerSide = (url: string) => {
      if (!url) return '';
      if (url.startsWith('http')) return url;
      if (url.startsWith('//')) return `https:${url}`;
      return `${origin}${url.startsWith('/') ? '' : '/'}${url}`;
    };

    const resolvedImageUrl = getAbsoluteImageUrlServerSide(imageUrl);

    console.log("Property Data:", {
      companyName,
      tenantId,
      stage,
      firstName,
      imageUrl,
      headerText,
      resolvedImageUrl,
      fullUrl,
    });

    return {
      props: {
        propertyData: {
          companyName,
          tenantId,
          stage,
          firstName,
          imageUrl,
          headerText,
          resolvedImageUrl,
          fullUrl,
        },
      },
    };
  } catch (error) {
    console.error('Error processing data in getServerSideProps:', error);
    return {
      props: { propertyData: null },
    };
  }
};

export default IndexPage;

子组件:src/components/Sharing/Property.tsx

import React from 'react';
import { Box, Typography, Button, Card, CardMedia, CardContent } from '@mui/material';
import Link from 'next/link';
import Head from 'next/head';
import styles from 'styles/ShareButton.module.scss';

interface PropertyProps {
  companyName: string;
  tenantId: string;
  stage: string;
  firstName: string;
  imageUrl: string;
  headerText?: string;
  resolvedImageUrl: string;
  fullUrl: string;
}

const Property = ({
  companyName,
  tenantId,
  stage,
  firstName,
  imageUrl,
  headerText = "Property Update",
  resolvedImageUrl,
  fullUrl
}: PropertyProps) => {
  return (
    <Box sx={{ maxWidth: 800, margin: '0 auto', padding: 3 }}>
      <Card elevation={3}>
        <CardMedia
          component="img"
          height="400"
          image={resolvedImageUrl}
          alt={`Property update from ${companyName}`}
        />
        <CardContent>
          <Typography variant="h4" component="h1" gutterBottom>
            {headerText}
          </Typography>
          <Typography variant="body1" color="text.secondary" paragraph>
            Hi {firstName}, here's your latest property update from {companyName}.
          </Typography>
          <Typography variant="body1" paragraph>
            Current stage: {stage}
          </Typography>
          <Link href={fullUrl} passHref>
            <Button variant="contained" color="primary">
              View Full Details
            </Button>
          </Link>
        </CardContent>
      </Card>
    </Box>
  );
};

export default Property;

我已经用了getServerSideProps来做服务端渲染,按道理爬虫请求的时候应该能拿到完整渲染后的HTML(包含OG标签),但实际Network的Response里就是没有这些标签。有没有大佬能帮我分析下问题出在哪?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 11:09:35