当前位置: 首页 > news >正文

SPA单页面应用优化SEO

1.SSR服务端渲染

将组件或页面通过服务器生成html,再返回给浏览器,如nuxt.js或vue-server-renderer

const Vue = require('vue');
const server = require('express')();
const renderer = require('vue-server-renderer').createRenderer();const vueApp = new Vue({data() {return {url: 'http://localhost:8080'}},template: `<div>访问的URL是: {{ url }}</div>`
});server.get('*', (req, res) => {const context = {url: req.url};renderer.renderToString(vueApp, context, (err, html) => {if (err) {res.status(500).end('Internal Server Error');return;}res.end(`<!DOCTYPE html><html lang="en"><head><title>Hello</title></head><body>${html}</body></html>`);});
});server.listen(8080);

2.静态化

目前主流的静态化主要有两种:
(1)通过程序将动态页面抓取并保存为静态页面,这样的页面的实际存在于服务器的硬盘中。


假设我们有一个简单的Node.js应用,它使用Express框架来处理路由,并使用Puppeteer来抓取页面并保存为静态HTML。

const express = require('express');
const puppeteer = require('puppeteer');
const fs = require('fs');const app = express();app.get('/generate-static', async (req, res) => {const browser = await puppeteer.launch();const page = await browser.newPage();await page.goto('http://localhost:3000/page2', {waitUntil: 'networkidle2'});const content = await page.content();await browser.close();fs.writeFile('static/page2.html', content, (err) => {if (err) {return res.status(500).send('Error saving static file');}res.send('Static file generated successfully');});
});app.get('/page2', (req, res) => {res.send('<html><body><h1>Page 2 Content</h1></body></html>');
});app.use(express.static('static'));app.listen(3000, () => {console.log('Server is running on http://localhost:3000');
});

(2)通过WEB服务器的 URL Rewrite的方式,它的原理是通过URL重写将静态URL映射到动态处理逻辑,最终返回的是静态内容;

首先,假设我们有一个简单的Node.js应用,提供动态内容:

const express = require('express');
const app = express();app.get('/dynamic-page2', (req, res) => {res.send('<html><body><h1>Dynamic Page 2 Content</h1></body></html>');
});app.listen(3000, () => {console.log('Server is running on http://localhost:3000');
});

配置Nginx以实现URL重写,当用户访问http://example.com/page2时,Nginx会将请求重写为/dynamic-page2,然后代理到运行在localhost:3000的Express应用。尽管URL看起来是静态的,但实际上返回的是动态生成的内容。

server {listen 80;server_name example.com;location /page2 {rewrite ^/page2$ /dynamic-page2 break;proxy_pass http://localhost:3000;}location / {proxy_pass http://localhost:3000;}
}

 3.针对爬虫处理

通过检查请求头中的 User-Agent 来判断请求是否来自爬虫,如果是爬虫请求,则使用 Puppeteer 生成页面;

const express = require('express');
const puppeteer = require('puppeteer');const app = express();
const PORT = 3000;// 中间件:检查用户代理是否为爬虫
const isCrawler = (req) => {const userAgent = req.headers['user-agent'];return /Googlebot|Bingbot|Baidu|Tencent|Sogou/.test(userAgent);
};// 路由处理
app.get('/', async (req, res) => {if (isCrawler(req)) {// 如果是爬虫请求,则使用 Puppeteer 生成页面const browser = await puppeteer.launch();const page = await browser.newPage();// 访问需要爬取的 URLawait page.goto('https://example.com', { waitUntil: 'networkidle0' });// 获取生成的 HTMLconst content = await page.content();// 关闭浏览器await browser.close();// 返回爬虫请求的 HTMLres.send(content);} else {// 正常用户的请求可以返回一个简单的提示res.send('<h1>欢迎访问我们的网站!</h1>');}
});// 启动服务器
app.listen(PORT, () => {console.log(`Server is running at http://localhost:${PORT}`);
});

相关文章:

SPA单页面应用优化SEO

1.SSR服务端渲染 将组件或页面通过服务器生成html&#xff0c;再返回给浏览器&#xff0c;如nuxt.js或vue-server-renderer const Vue require(vue); const server require(express)(); const renderer require(vue-server-renderer).createRenderer();const vueApp new …...

城市霓虹灯夜景拍照后期Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色教程 在城市霓虹灯夜景拍摄中&#xff0c;由于现场光线复杂等因素&#xff0c;照片可能无法完全呈现出当时的视觉感受。通过 Lr 调色&#xff0c;可以弥补拍摄时的不足。例如&#xff0c;运用基本调整面板中的曝光、对比度、阴影等工具&#xff0c;可以处理出画面的整体明暗…...

通领科技冲刺北交所

高质量增长奔赴产业新征程 日前&#xff0c;通领科技已正式启动在北交所的 IPO 进程&#xff0c;期望借助资本市场的力量&#xff0c;加速技术升级&#xff0c;推动全球化战略布局。这一举措不仅展现了中国汽车零部件企业的强大实力&#xff0c;也预示着行业转型升级的新突破。…...

隐私保护在 Facebook 用户身份验证中的应用

在这个数字化的时代&#xff0c;个人隐私保护成为了公众关注的焦点。社交媒体巨头 Facebook 作为全球最大的社交平台之一&#xff0c;拥有数十亿用户&#xff0c;其在用户身份验证过程中对隐私保护的重视程度直接影响着用户的安全感和信任度。本文将探讨 Facebook 在用户身份验…...

深度学习/强化学习调参技巧

深度调优策略 1. 学习率调整 技巧&#xff1a;学习率是最重要的超参数之一。过大可能导致训练不稳定&#xff0c;过小则收敛速度慢。可以使用学习率衰减&#xff08;Learning Rate Decay&#xff09;或自适应学习率方法&#xff08;如Adam、RMSprop&#xff09;来动态调整学习…...

python面试常见题目

1、python 有几种数据类型 数字:整形 &#xff08;int&#xff09;,浮点型 &#xff08;float&#xff09;布尔 &#xff08; bool&#xff09;:false true字符串 &#xff08;string&#xff09;列表 &#xff08;list&#xff09;元组 &#xff08;tuple&#xff09;字典 &…...

echarts折线图设置背景颜色:X轴和Y轴组成部分背景色

echarts折线图设置背景颜色 关键代码 splitArea: {show: true,areaStyle: {color: [#F2F2F2],},},完整代码位置显示 yAxis: {type: value,boundaryGap: [0, 100%],max: 1,interval: 1,// 于设置y轴的字体axisLabel: {show: false, //这里的show用于设置是否显示y轴下的字体 默…...

文本处理Bert面试内容整理-BERT的应用场景有哪些?

BERT(Bidirectional Encoder Representations from Transformers)在多个自然语言处理(NLP)任务中表现出了强大的能力。由于其能够捕捉双向上下文信息和强大的迁移学习能力,BERT广泛应用于各种NLP场景。以下是BERT的一些典型应用场景: 1. 文本分类 文本分类任务旨在将文本…...

【愚公系列】《Python网络爬虫从入门到精通》045-Charles的SSL证书的安装

标题详情作者简介愚公搬代码头衔华为云特约编辑&#xff0c;华为云云享专家&#xff0c;华为开发者专家&#xff0c;华为产品云测专家&#xff0c;CSDN博客专家&#xff0c;CSDN商业化专家&#xff0c;阿里云专家博主&#xff0c;阿里云签约作者&#xff0c;腾讯云优秀博主&…...

manus对比ChatGPT-Deep reaserch进行研究类学术相关数据分析!谁更胜一筹?

没有账号&#xff0c;只能挑选一个案例 一夜之间被这个用全英文介绍全华班出品的新爆款国产AI产品的小胖刷频。白天还没有切换语言的选项&#xff0c;晚上就加上了。简单看了看团队够成&#xff0c;使用很长实践的Monica创始人也在其中。逐渐可以理解&#xff0c;重心放在海外产…...

20250307确认荣品PRO-RK3566开发板在Android13下的以太网络共享功能

20250307确认荣品PRO-RK3566开发板在Android13下的以太网络共享功能 2025/3/7 13:56 缘起&#xff1a;我司地面站需要实现“太网络共享功能”功能。电脑PC要像连接WIFI热点一样连接在Android设备/平板电脑上来实现上网功能/数据传输。 Android设备/平板电脑通过4G/WIFI来上网。…...

Unity Job系统详解原理和基础应用处理大量物体位置

概述 该脚本使用 Unity Job System 和 Burst Compiler 高效管理大量剑对象的位移计算与坐标更新。通过双缓冲技术实现无锁并行计算&#xff0c;适用于需要高性能批量处理Transform的场景。 核心类 SwordManager 成员变量 变量名类型说明swordPrefabGameObject剑对象预制体_d…...

高效编程指南:PyCharm与DeepSeek的完美结合

DeepSeek接入Pycharm 前几天DeepSeek的充值窗口又悄悄的开放了&#xff0c;这也就意味着我们又可以丝滑的使用DeepSeek的API进行各种辅助性工作了。本文我们来聊聊如何在代码编辑器中使用DeepSeek自动生成代码。 注&#xff1a;本文适用于所有的JetBrains开发工具&#xff0c…...

Facebook 的隐私保护数据存储方案研究

Facebook 的隐私保护数据存储方案研究 在这个信息爆炸的时代&#xff0c;数据隐私保护已成为公众关注的热点。Facebook&#xff0c;作为全球最大的社交媒体平台之一&#xff0c;承载着海量用户数据&#xff0c;其隐私保护措施和数据存储方案对于维护用户隐私至关重要。本文将深…...

c#面试题整理

1.如何保持数据库的完整性&#xff0c;一致性 最好的方法&#xff1a;数据库约束&#xff08;check,unique,主键&#xff0c;外键&#xff0c;默认&#xff0c;非空&#xff09; 其次是&#xff1a;用触发器 最后&#xff1a;才是自己些业务逻辑&#xff0c;这个效率低 2.事…...

车载以太网测试-4车载以太网如何进行通信的?

1 摘要 车载以太网的数据传输与接收遵循分层网络架构&#xff08;如OSI模型或TCP/IP模型&#xff09;&#xff0c;从应用层到物理层需要逐层封装与解封装。本文将对车载以太网的数据传输流程进行介绍。 2 以太网通信过程&#xff08;封装与解封装&#xff09; 2.1 发送端流程…...

R软件线性模型与lmer混合效应模型对生态学龙类智力测试数据层级结构应用

全文链接&#xff1a;https://tecdat.cn/?p40925 在生态与生物学研究中&#xff0c;数据常呈现复杂结构特征。例如不同种群、采样点或时间序列的观测数据间往往存在相关性&#xff08;点击文末“阅读原文”获取完整代码、数据、文档&#xff09;。 传统线性模型在处理这类非独…...

WIFI ESP8266以及基础功能介绍

芯片一旦烧写了程序就不可以使用AT指令集&#xff0c;需要重新刷回AT指令库才可以使用 wifi的通信频段是2.4G免费频段。 AT指令 AT&#xff08;attention&#xff09;command set.AT指令集或命令集&#xff0c;一般称为AT指令 海斯命令集&#xff1a;Hayes command set 默认…...

HarmonyOS ArkTS声明式UI开发实战教程

引言&#xff1a;为何选择ArkTS&#xff1f; 在HarmonyOS生态快速发展的当下&#xff0c;ArkTS作为新一代声明式UI开发框架&#xff0c;正在引发移动应用开发范式的变革。笔者曾在多个跨平台框架开发中经历过"命令式编程之痛"&#xff0c;直到接触ArkTS后才发现&…...

FPGA之USB通信实战:基于FX2芯片的Slave FIFO回环测试详解

FPGA之Usb数据传输 Usb 通信 你也许会有疑问&#xff0c;明明有这么多通信方式和数据传输&#xff08;SPI、I2C、UART、以太网&#xff09;为什么偏偏使用USB呢? 原因有很多&#xff0c;如下&#xff1a; 1. 高速数据传输能力 高带宽&#xff1a;USB接口提供了较高的数据传…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...