【网站深入seo方法】

发布于:2025-08-13 ⋅ 阅读:(23) ⋅ 点赞:(0)

目录

①对于更成熟的网站,简单的index.html的入口文件的seo已经无法满足,需要在商品详情不同商品被搜索时赋予不同的title和description。

②通过设置站点所有页面都新增Canonical标签,指定规范链接地址给谷歌并规避联盟的重复内容页面。

③产品结构化微数据


①对于更成熟的网站,简单的index.html的入口文件的seo已经无法满足,需要在商品详情不同商品被搜索时赋予不同的title和description。

<!-- src/views/main/goods/goods-details/goods-details.vue -->
<template>
  <!-- 模板部分保持不变 -->
</template>

<script>
// ... 其他导入保持不变

export default {
  name: "goods-details",
  // ... 其他配置保持不变
  data() {
    return {
      // ... 其他数据保持不变
      originalMetaTags: {} // 保存原始meta标签
    }
  },
  // ... 其他配置保持不变
  methods: {
       // 设置产品页面的SEO信息
    setProductSEO(dataInfo) {
      if (!dataInfo) return;
      // 保存原始的meta标签信息(只在第一次调用时保存)
      if (!this.originalMetaTags.title) {
        this.originalMetaTags.title = document.title;
        this.originalMetaTags.description = this.getMetaContent('name', 'description');
        this.originalMetaTags['og:title'] = this.getMetaContent('property', 'og:title');
        this.originalMetaTags['og:description'] = this.getMetaContent('property', 'og:description');
        this.originalMetaTags['twitter:title'] = this.getMetaContent('name', 'twitter:title');
        this.originalMetaTags['twitter:description'] = this.getMetaContent('name', 'twitter:description');
      }
      // 获取产品标题
      const productTitle = dataInfo.subject || '';
      // 设置新的页面标题
      const newTitle = `Buy ${productTitle} | Hipobuy`;
      document.title = newTitle;
      // 设置新的meta description
      const newDescription = `Find the perfect ${productTitle} on Taobao or 1688? Hipobuy is your trusted China shopping agent. Start shopping now!`;
      // 更新所有meta标签
      this.updateMetaTag('name', 'description', newDescription);
      this.updateMetaTag('property', 'og:title', newTitle);
      this.updateMetaTag('property', 'og:description', newDescription);
      this.updateMetaTag('name', 'twitter:title', newTitle);
      this.updateMetaTag('name', 'twitter:description', newDescription);
    },
    // 获取meta标签内容的辅助方法
    getMetaContent(attribute, value) {
      const metaTag = document.querySelector(`meta[${attribute}="${value}"]`);
      return metaTag ? metaTag.getAttribute('content') : '';
    },

    // 更新meta property标签
    updateMetaProperty(property, content) {
      let metaTag = document.querySelector(`meta[property="${property}"]`);
      if (metaTag) {
        metaTag.setAttribute('content', content);
      } else {
        metaTag = document.createElement('meta');
        metaTag.setAttribute('property', property);
        metaTag.content = content;
        document.head.appendChild(metaTag);
      }
    },

    // 更新meta标签的通用方法
    updateMetaTag(attribute, value, content) {
      let metaTag = document.querySelector(`meta[${attribute}="${value}"]`);
      if (metaTag) {
        metaTag.setAttribute('content', content);
      } else {
        metaTag = document.createElement('meta');
        metaTag.setAttribute(attribute, value);
        metaTag.content = content;
        document.head.appendChild(metaTag);
      }
    },

    // 完整恢复原始meta标签(页面销毁时调用)
    restoreOriginalMetaTags() {
      // 恢复title
      if (this.originalMetaTags.title) {
        document.title = this.originalMetaTags.title;
      }
      // 恢复description
      if (this.originalMetaTags.description !== undefined) {
        const descriptionMeta = document.querySelector('meta[name="description"]');
        if (descriptionMeta) {
          if (this.originalMetaTags.description) {
            descriptionMeta.setAttribute('content', this.originalMetaTags.description);
          } else {
            descriptionMeta.remove(); // 如果原来没有,就删除添加的
          }
        } else if (this.originalMetaTags.description) {
          // 如果原来有但现在没有,就重新创建
          const meta = document.createElement('meta');
          meta.name = 'description';
          meta.content = this.originalMetaTags.description;
          document.head.appendChild(meta);
        }
      }

      // 恢复og:title
      this.restoreMetaTag('property', 'og:title', this.originalMetaTags['og:title']);
      // 恢复og:description
      this.restoreMetaTag('property', 'og:description', this.originalMetaTags['og:description']);
      // 恢复twitter:title
      this.restoreMetaTag('name', 'twitter:title', this.originalMetaTags['twitter:title']);
      // 恢复twitter:description
      this.restoreMetaTag('name', 'twitter:description', this.originalMetaTags['twitter:description']);
    },

    // 恢复单个meta标签的辅助方法
    restoreMetaTag(attribute, value, originalContent) {
      const metaTag = document.querySelector(`meta[${attribute}="${value}"]`);
      if (metaTag) {
        if (originalContent) {
          metaTag.setAttribute('content', originalContent);
        } else {
          metaTag.remove(); // 如果原来没有,删除添加的标签
        }
      } else if (originalContent) { // 如果原来有但现在没有,重新创建
        const meta = document.createElement('meta');
        meta.setAttribute(attribute, value);
        meta.content = originalContent;
        document.head.appendChild(meta);
      }
    },
    
    getQueryProductDetail(force) {
      this.loading = true;
      queryProductDetail({
        spuNo: this.id,
        refresh: !!force ? 1 : 0,
        channel: this.channel,
        activityCode: this.activityCode
      }).then((res) => {
        if (res.code == 1010) {
          this.loading = false;
          this.$refs.tipsPopRef.open(res.message);
        } else if (res.code == 200) {
          if (res.result.productGrayscale) {
            this.$refs.grayPopRef.open(res.result.productGrayscaleName)
          }

          this.loading = false;
          this.dataInfo = res.result;
          this.dataInfo.description = this.dataInfo.description.replace(/\s*href="[^"]*"/gi, '');

          // 设置产品SEO信息——getQueryProductDetail此请求只添加了这个设置,其余不需改动
          this.setProductSEO(this.dataInfo);

          if (this.dataInfo.channel == 'TAOBAO') {
            detailPointBtn(this.$route.params.spuNo, 'EXP', 'buy_icon');
            detailPointBtn(this.$route.params.spuNo, 'EXP', 'addcart_icon');
          }

          if (res.result.spuActivityVO) {
            if (this.$analytics) {
              this.$analytics.logEvent('pt_1001');
            }
          }
        }
      }).catch(() => {
        this.loading = false;
      })
    },
    
    // ... 其他方法保持不变
  },
  

  beforeDestroy() {// 恢复原始的meta标签
    this.restoreOriginalMetaTags();
  }
}
</script>

<!-- 样式部分保持不变 -->

本地环境自测以html的标签为准即可;

②通过设置站点所有页面都新增Canonical标签,指定规范链接地址给谷歌并规避联盟的重复内容页面。

处理带有URL参数的页面

场景:电商网站的产品页面可能会因为不同的筛选条件(如颜色、尺寸、排序方式等)而生成带有不同参数的URL。
示例:https://example.com/product?id=123&color=blue
https://example.com/product?id=123&size=large
解决方案:在所有带参数的页面中,使用Canonical标签指向主要的产品页面,如:

<link rel="canonical" href="https://example.com/product?id=123" />

分页内容

场景:文章列表或产品列表页面经常会分页(如第1页、第2页)
示例:https://example.com/blog?page=1
https://example.com/blog?page=2
解决方案:可以让每个分页页面的Canonical标签指向第一页,或者让每页的Canonical标签指向自身。<link rel="canonical" href="https://example.com/blog?page=1" />

内容分发与跟踪参数

场景:网站在不同渠道(如社交媒体)分发内容,带有UTM等跟踪参数
示例:https://example.com/blog/post?utm_source=facebook
解决方案:使用Canonical标签指向无参数的主要URL.

<link rel="canonical" href="https://example.com/blog/post" />

下面是我的实践实例动态设置所有页面:

<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en-US">
<head>
    <!-- 其他head内容保持不变 -->
    
    <!-- 添加基础canonical标签 -->
    <link rel="canonical" href="https://hipobuy.com/" />
    
    <!-- 其他head内容保持不变 -->
</head>
<body>
    <div id="app"></div>
</body>
</html>
// 在 src/router/index.js 中添加
router.afterEach((to) => {
  // 延迟执行确保DOM已更新
  setTimeout(() => {
    const canonicalLink = document.querySelector('link[rel="canonical"]');
    if (canonicalLink) {
      // 获取基础URL,移除查询参数和hash
      const baseUrl = window.location.origin;
      const pathname = to.path;
      const canonicalUrl = baseUrl + pathname;
      
      canonicalLink.href = canonicalUrl;
    }
  }, 100);
});

特殊情况:电商网站中如果路由配置了参数可以用这种配置,不过具体在控制台查看link标签,我发现以上路由设置已经足够,可以把参数也带进canonical标签,如果不行参考以下:

<!-- 在 src/views/main/goods/goods-details/goods-details.vue 的 methods 中添加 -->
methods: {
  // ... 其他方法保持不变
  
  // 添加这个方法来设置产品页的canonical
  setProductCanonical() {
    const canonicalLink = document.querySelector('link[rel="canonical"]');
    if (canonicalLink) {
      // 构建产品页的标准canonical URL
      const channelMap = {
        "0": "1688",
        "1": "taobao",
        "2": "weidian",
        "3": "jd"
      };
      
      const channelName = channelMap[this.channel] || this.channel.toLowerCase();
      const canonicalUrl = `https://hipobuy.com/product/${channelName}/${this.id}`;
      canonicalLink.href = canonicalUrl;
    }
  },
  
  // 在 getQueryProductDetail 方法的成功回调中调用
  getQueryProductDetail(force) {
    // ... 其他代码保持不变
    queryProductDetail({
      // ... 参数保持不变
    }).then((res) => {
      // ... 其他成功处理保持不变
      if (res.code == 200) {
        // ... 其他处理保持不变

        // 设置产品SEO信息
        this.setProductSEO(this.dataInfo);
        // 添加这一行来设置产品页canonical
        this.setProductCanonical();

        // ... 其他处理保持不变
      }
    }).catch(() => {
      this.loading = false;
    })
  }
}

③产品结构化微数据

这是代码效果示例,不可以直接添加在html:

<html>
  <head>
    <title>Executive Anvil</title>
    <script type="application/ld+json">
      {
        "@context": "https://schema.org/",
        "@type": "Product",
        "name": "Executive Anvil",
        "image": [
          "https://example.com/photos/1x1/photo.jpg",
          "https://example.com/photos/4x3/photo.jpg",
          "https://example.com/photos/16x9/photo.jpg"
         ],
        "description": "Sleeker than ACME's Classic Anvil, the Executive Anvil is perfect for the business traveler looking for something to drop from a height.",
        "sku": "0446310786",
        "mpn": "925872",
        "brand": {
          "@type": "Brand",
          "name": "ACME"
        },
        "review": {
          "@type": "Review",
          "reviewRating": {
            "@type": "Rating",
            "ratingValue": 4,
            "bestRating": 5
          },
          "author": {
            "@type": "Person",
            "name": "Fred Benson"
          }
        },
        "aggregateRating": {
          "@type": "AggregateRating",
          "ratingValue": 4.4,
          "reviewCount": 89
        },
        "offers": {
          "@type": "AggregateOffer",
          "offerCount": 5,
          "lowPrice": 119.99,
          "highPrice": 199.99,
          "priceCurrency": "USD"
        }
      }
    </script>
  </head>
  <body>
  </body>
</html>

以下才是js效果代码:

<!-- src/views/main/goods/goods-details/goods-details.vue -->
<script>
export default {
  name: "goods-details",
  // ... 其他代码保持不变
  data() {
    return {
      // ... 其他数据保持不变
      structuredDataScript: null // 保存结构化数据script元素
    }
  },
  methods: {
    // 生成并插入结构化数据
    generateStructuredData(dataInfo) {
      if (!dataInfo) return;
      // 移除已存在的结构化数据
      this.removeStructuredData();
      // 构建基础产品信息
      const structuredData = {
        "@context": "https://schema.org/",
        "@type": "Product",
        "name": dataInfo.subject || '',
        "image": this.getProductImages(dataInfo),
        "description": this.getProductDescription(dataInfo),
        "sku": dataInfo.spuNo || '',
        "mpn": dataInfo.spuNo || dataInfo.id || '',
        "brand": this.getProductBrand(dataInfo),
        "offers": this.getProductOffers(dataInfo)
      };
      // 添加评分信息
      const ratingInfo = this.getProductRating(dataInfo);
      if (ratingInfo) {
        structuredData.aggregateRating = ratingInfo;
      }
      // 添加评论信息(如果有)
      const reviews = this.getProductReviews(dataInfo);
      if (reviews && reviews.length > 0) {
        structuredData.review = reviews;
      }
      // 创建script标签并插入到head中
      this.structuredDataScript = document.createElement('script');
      this.structuredDataScript.type = 'application/ld+json';
      this.structuredDataScript.textContent = JSON.stringify(structuredData, null, 2);
      // 添加标识便于清理
      this.structuredDataScript.setAttribute('data-structured-data', 'product');
      document.head.appendChild(this.structuredDataScript);
    },
    // 获取产品图片列表
    getProductImages(dataInfo) {
      const images = [];
      // 主图
      if (dataInfo.mainImg) {
        images.push(dataInfo.mainImg);
      }
      // 图片列表
      if (dataInfo.imageList && Array.isArray(dataInfo.imageList)) {
        images.push(...dataInfo.imageList);
      }
      // 去重
      return [...new Set(images)].slice(0, 10); // 最多10张图片
    },
    // 获取产品描述
    getProductDescription(dataInfo) {
      if (!dataInfo.description) return '';
      // 移除HTML标签
      const tmp = document.createElement('div');
      tmp.innerHTML = dataInfo.description;
      return tmp.textContent || tmp.innerText || '';
    },
    // 获取品牌信息
    getProductBrand(dataInfo) {
      const channelNames = {
        "0": "1688",
        "1": "Taobao",
        "2": "Weidian",
        "3": "JD",
        "1688": "1688",
        "TAOBAO": "Taobao",
        "WEIDIAN": "Weidian",
        "JD": "JD"
      };
      const brandName = dataInfo.brandName ||
        channelNames[dataInfo.channel] ||
        channelNames[this.channel] ||
        "Chinese E-commerce Platform";
      return {
        "@type": "Brand",
        "name": brandName
      };
    },
    // 获取产品报价信息
    getProductOffers(dataInfo) {
      const price = this.getProductPrice(dataInfo);
      const currency = dataInfo.currencyCode || "CNY";
      const availability = this.getAvailabilityStatus(dataInfo);
      return {
        "@type": "Offer",
        "url": window.location.href,
        "priceCurrency": currency,
        "price": price,
        "availability": availability,
        "priceValidUntil": this.getPriceValidUntil(),
        "seller": {
          "@type": "Organization",
          "name": "Hipobuy"
        }
      };
    },
    // 获取产品价格
    getProductPrice(dataInfo) {
      if (dataInfo.price) {
        return dataInfo.priceCNY ? dataInfo.priceCNY : dataInfo.price;
      } else if (dataInfo.saleInfo) {
        if (dataInfo.saleInfo.priceRangeList && dataInfo.saleInfo.priceRangeList.length > 0) {
          return dataInfo.saleInfo.priceRangeList[0].priceCNY ?
            dataInfo.saleInfo.priceRangeList[0].priceCNY :
            dataInfo.saleInfo.priceRangeList[0].price;
        } else if (dataInfo.saleInfo.priceRanges && dataInfo.saleInfo.priceRanges.length > 0) {
          return dataInfo.saleInfo.priceRanges[0].priceCNY ?
            dataInfo.saleInfo.priceRanges[0].priceCNY :
            dataInfo.saleInfo.priceRanges[0].price;
        }
      }
      return "0";
    },
    // 获取产品评分信息
    getProductRating(dataInfo) {
      if (dataInfo.score || dataInfo.commentNum) {
        return {
          "@type": "AggregateRating",
          "ratingValue": dataInfo.score || 0,
          "reviewCount": dataInfo.commentNum || 0,
          "bestRating": 5,
          "worstRating": 1
        };
      }
      return null;
    },
    // 获取产品评论信息
    getProductReviews(dataInfo) {
      // 如果有具体的评论数据,可以在这里处理
      // 目前返回空数组
      return [];
    },
    // 获取库存状态
    getAvailabilityStatus(dataInfo) {
      // 根据库存信息判断可用性
      if (dataInfo.stock !== undefined) {
        return dataInfo.stock > 0 ? "https://schema.org/InStock" : "https://schema.org/OutOfStock";
      }
      // 根据状态判断
      if (dataInfo.status !== undefined) {
        switch (dataInfo.status) {
          case 'ON_SALE':
          case 'AVAILABLE':
            return "https://schema.org/InStock";
          case 'SOLD_OUT':
          case 'OFF_SALE':
            return "https://schema.org/OutOfStock";
          default:
            return "https://schema.org/InStock";
        }
      }
      return "https://schema.org/InStock"; // 默认有库存
    },
    // 获取价格有效期
    getPriceValidUntil() {
      const date = new Date();
      date.setMonth(date.getMonth() + 3); // 价格有效期3个月
      return date.toISOString().split('T')[0];
    },
    // 移除结构化数据
    removeStructuredData() {
      if (this.structuredDataScript) {
        document.head.removeChild(this.structuredDataScript);
        this.structuredDataScript = null;
      }
    },
  },
  
  // 组件销毁时移除结构化数据
  beforeDestroy() {
    this.removeStructuredData(); // 移除结构化数据
  }
}
</script>
          // 生成结构化数据---------在调用商品详情的接口内调用并传递res.dataInfo
          this.generateStructuredData(this.dataInfo);

执行完之后可以在控制台head标签内查找是否展现:


网站公告

今日签到

点亮在社区的每一天
去签到