☰
从零开始做第一个网站:静态页面到上线全流程指南
2026/9/24 22:36:39 网站建设 项目流程

做我的第一个网站那年,我在虚拟机里折腾了整整一周,最后打开网址的那一刻,地址栏里跳出来的居然真的是我写的页面,那种感觉比考试拿满分还爽。那个页面其实丑得不行,白底黑字,没有图片,图片还因为路径写错挂了一半,但对我而言,它意味着“我把一个想法变成了一个互联网上真实存在的东西”。这篇文章不打算讲什么高深框架,也不准备让读者一上来就动后端、接数据库,就老老实实把新手做第一个网站时一定要经历的完整链路拆开:本地文件怎么写、怎么调试、怎么部署上线、上线后碰到打不开或样式丢失该怎么排查。只要耐心看完,再跟着操作一遍,大概率也能拥有自己的第一个网站。

1. 为什么第一个网站应该从纯静态页面开始

1.1 静态页面和动态网站的真实区别

很多新手对“网站”的理解是模糊的,总觉得网站就等于“有后台、能登录、能存数据”的那种东西。实际上,网站可以粗略分成两类:静态网站和动态网站。

静态网站,就是服务器上放着已经写好的HTML、CSS、JavaScript文件,浏览器请求某个地址,服务器把这个文件原样返回给浏览器,浏览器负责解析渲染。整个过程没有程序运算,也没有数据库参与。

动态网站则不同。用户在浏览器里看到的内容,是服务器端程序(比如PHP、Python、Java)实时运行后生成的。程序可以读写数据库、处理表单、区分登录状态,同一个URL在不同时间、不同用户访问时,返回的内容可能完全不一样。

我第一次做网站时,其实完全没搞清楚这个区别,属于闷头写了一个静态页面,结果心里想着“我要做个完整的网站”,这反而歪打正着走了一条最正确的路。因为第一目标不该是“做一个功能大全”,而该是“让一个页面能从自己的电脑跑到公网,被别人访问到”。

1.2 为什么不用建站工具,而要亲手写

现在建站工具特别多,拖拽几下模板就出来了,速度确实快。但问题在于,用这些工具做出来的东西,本质上是“套壳”,不是“制作”。

我当时也试过几个建站工具,拖了个导航栏、放了几张图,看着挺像样。可一旦要改点细节,比如把导航栏稍微往上挪一点,或者让某个元素在手机端换个排列方式,就完全不知道从哪下手。那种感觉很憋屈——你拥有一个东西,却不了解它的结构,只能等待功能让做什么就做什么。

亲手写一遍HTML、CSS和JavaScript,最大的好处是建立“结构感”。你会知道页面是由标签组成的,样式是由规则叠加的,交互是由事件触发的。有了这层底子,后面再接触任何建站工具、页面可视化编辑器,哪怕是最新出的AI生成网站工具,你都能看懂它生成的代码,知道自己要改哪里。没有这层底子,你永远只是个使用者,不是制作者。

1.3 这个阶段的学习目标与时间线

我建议第一个网站阶段,把目标定得非常小:做一个包含几个版块的单页面,有标题、有段落、有图片、有一个能点出反应的按钮,最后能通过域名被朋友访问到。

这个目标对应的技能只有三样:HTML负责内容结构,CSS负责外观样式,JavaScript负责交互逻辑。不需要碰数据库、不需要写后端、不需要理解复杂的服务器架构。

时间上,一个完全没有基础的成年人,认真花两个周末基本能跑通。我自己那会儿还走了不少弯路,比如在编辑器选择上纠结了半天,又在路径问题上卡了一晚上。这篇文章会把容易卡住的地方提前标出来,你按着顺序走,效率肯定比我高。

2. 动手前做准备:编辑器、浏览器与本地预览

2.1 选编辑器:为什么推荐 VS Code

工欲善其事,必先利其器。做网站编辑器是绕不开的,我见过有人用记事本写HTML,能写,但效率太低,没有语法高亮、没有自动补全,少写个闭合标签都很难发现,尤其对新手极不友好。

我常用的编辑器是 VS Code,免费、跨平台、插件生态非常成熟。装好之后,强烈建议再装两个插件:一个叫Live Server,用来在本地启动一个临时服务器,实现“改完代码浏览器立刻刷新”;另一个是HTML CSS Support,写标签和类名时能给提示,减少拼写错误。

编辑器安装本身没什么难度,下载安装包一路下一步就行。有一点需要你养成习惯:新建一个专门的项目文件夹,所有网站文件都放里面,不要随手扔在桌面或下载目录。后面部署上线时,这个文件夹就是网站的本体,整整齐齐会省很多事。

提示:项目文件夹路径中尽量不要出现中文和空格。虽然现代工具大多能处理,但有些服务器配置或命令行操作会因此报错,这是一类完全可以提前避免的问题。

2.2 项目目录结构:从一开始就规划

我第一次做网站的时候,所有文件平铺在一个文件夹里,HTML、CSS、图片混成一锅粥。后来文件一多,找一个样式文件要找半天。后来我学乖了,给项目做了一个基础目录结构,你可以直接抄作业:

my-website/ ├── index.html ├── css/ │ └── style.css ├── js/ │ └── main.js └── images/

这里有几个约定俗成的规矩,值得一开始就知道:

  • index.html是网站的默认首页。服务器在收到访问根目录的请求时,会优先查找这个文件。如果你给它起名叫home.html,用户访问域名时反而会看到目录列表或错误页。
  • css、js、images分别放样式、脚本、图片,分类管理。
  • 文件名全部用小写字母,单词间用连字符-分隔,比如about-page.html,不要用空格,也不要用中文文件名。原因很简单——服务器多基于Linux系统,文件和目录是区分大小写的,而且URL编码中文会出现一大堆%E4%BD%A0这样的符号,既难看又容易出错。

2.3 本地预览的两种方式

写完代码想看效果,新手最容易用的方式是双击index.html,浏览器直接打开本地文件。这种方法能看,但有一个隐患:页面里如果使用了某些浏览器API,比如fetch请求本地数据、ES6模块引入,直接打开文件时会因为浏览器的安全策略而报错。

更好的方式是用编辑器里的Live Server插件。在 VS Code 里右键index.html,选择 “Open with Live Server”,它会在本地启动一个小型服务器,浏览器地址栏变成类似http://127.0.0.1:5500/index.html的样子。这个地址就是真实的HTTP访问方式,跟你将来上线后的访问方式本质上一致,能模拟线上环境,Nginx返回静态文件也是这个逻辑。

我个人的建议是:从一开始就用Live Server。养成“通过HTTP访问自己页面”的习惯,你会更早理解浏览器和服务器之间的请求-响应关系,后续部署上线时会顺畅很多。

3. 第一张页面:HTML结构与CSS样式

3.1 HTML骨架是怎么一回事

HTML是网页的骨架,浏览器拿到HTML的纯文本后,逐行解析成页面结构。在index.html里输入感叹号!并按Tab键,VS Code会自动生成一个标准骨架,新手容易好奇每个标签到底干什么,我逐个解释一遍:

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>我的第一个网站</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <h1>你好,我是新手站长</h1> <p>这是我的第一个网站。</p> <script src="js/main.js"></script> </body> </html>
  • <!DOCTYPE html>是文档类型声明,告诉浏览器按现代标准渲染页面。少了它,浏览器可能进入“怪癖模式”,导致样式表现异常。
  • <html lang="zh-CN">声明页面语言是简体中文,浏览器翻译插件和阅读器会读取这个属性。
  • <head>里的内容不会直接显示在页面上,它存放页面的元信息:字符编码、视口设置、标题、样式引入。
  • <meta charset="UTF-8">指定编码,如果漏掉,中文可能会变成乱码。
  • <meta name="viewport">是移动端适配的重要标签,没有它,手机浏览器会按桌面宽度渲染页面,导致字小得像蚂蚁。
  • <title>显示在浏览器标签页上,也是搜索引擎判断页面主题的重要依据。
  • <body>里面才是用户能看到的一切。

3.2 往页面里放内容:标题、段落、图片、链接

HTML最常用的内容标签没有多少个,搞懂基础的那几个就够了:<h1>到<h6>是不同层级的标题,<p>是段落,<a>是链接,<img>是图片,<ul>和<li>是无序列表,<div>和<span>是通用容器,用于配合CSS做布局。

这里单独提醒一个新手特别容易“踩坑”的地方:图片路径。假设目录里有一张图片放在images/photo.jpg,在HTML里引用的标准写法是:

<img src="images/photo.jpg" alt="我的照片">

上面用的是相对路径,含义是“相对于当前HTML文件所在的目录”。因为index.html在项目根目录,所以直接写images/photo.jpg就能找到。

但如果你把HTML文件放在子目录里,比如pages/about.html,那图片路径就要写成../images/photo.jpg,两个点表示“往上一级目录”。图片路径写错是新手最常遇到的情况,页面上一堆“裂图”,F12打开控制台看到一片404报错,大概率就是路径层级搞错了。

alt属性也尽量别省略,它不仅帮助屏幕阅读器用户理解图片内容,而且在图片加载失败时,能显示一段文字说明,不至于显示一个空框。

3.3 CSS样式:让页面不再是白底黑字

光有HTML,页面就是白底黑字的“原始文档”形态。想让它变好看,就要引入CSS。在HTML骨架里,我们已经用<link>标签引入了css/style.css,接下来在CSS文件里写规则。

CSS的基本结构是:选择器 + 声明块。比如:

h1 { color: #2c3e50; font-size: 32px; text-align: center; }

这段代码的意思是:页面上所有h1标签的文字颜色变成深蓝色,字号32像素,水平居中。

再往下,新手一定要理解“盒子模型”。页面上的每一个元素,展示时都是一个矩形盒子,从内到外依次是:内容、内边距padding、边框border、外边距margin。理解盒子模型是后面做任何布局的基础。你可以给一个元素同时设置四个属性,观察它周边空间的变化:

.article { width: 600px; padding: 20px; margin: 40px auto; border: 1px solid #ddd; }

布局方面,我不建议现在还抱着浮动float不放手,直接用flex布局起步最划算。比如想让三个卡片水平排列并居中:

.cards { display: flex; justify-content: center; gap: 20px; }

Flex布局的学习成本不高,但解决实际问题的能力很强,现在的现代网站几乎都在用它,或者是基于它衍生出来的网格布局。

3.4 用DevTools直接看哪里出错

做网站有一半时间其实是在“调试”。我看到很多新手改代码靠猜,改一下刷新一下,找不到问题就乱改,这是效率最低的方式。

浏览器自带的开发者工具(DevTools)是调试的利器,按 F12 或右键选“检查”就能打开。里面有这么几个面板对新手最有用:

  • Elements(元素):可以实时查看页面的HTML结构和每个元素的计算后样式。最妙的是,你在里面修改样式,浏览器立即生效,而且不影响源文件,特别适合“试试哪种样式更好看”的场景。
  • Console(控制台):显示JavaScript报错信息。代码出问题时,这里是第一个要来看的地方。
  • Network(网络):记录页面上每一个资源的加载请求时间、状态、响应头。图片挂了、CSS没加载出来,在这里一眼就能看出是哪个文件404了。

我第一次做网站时,图片裂了我不知道怎么排查,右键查看图片地址,看到是一堆看不懂的路径,查了半天才发现多写了一层目录。用Network面板的话,看路径一眼就能找到问题所在。DevTools值得花一小时提前研究。

4. JavaScript:让页面从“能看”变成“能用”

4.1 一个最简单的点击事件

HTML和CSS负责页面静态呈现,JavaScript负责动态交互。我的第一个网页是一个个人介绍页,我当时给它加的第一个交互是:点击一个按钮,页面上的文字换一句话。

核心逻辑只有三步:选中按钮,监听点击,改变文字。

const button = document.querySelector('#changeTextBtn'); const desc = document.querySelector('#welcomeText'); button.addEventListener('click', function () { desc.textContent = '你已经成功触发了第一次点击事件!'; });

document.querySelector是页面元素选择器,参数跟CSS选择器写法一致,#表示id选择器,.表示class选择器。addEventListener是给元素绑定事件的入口,第一个参数是事件类型,第二个参数是触发后执行的函数。

这里要提一个新手容易困惑的点:脚本放在<body>底部是为了确保HTML先被解析,否则JavaScript执行时元素可能还不存在。后来随着JavaScript模块化普及,更多人会用DOMContentLoaded事件包裹代码,或者直接在HTML标签上加defer属性,但我个人觉得新手阶段先按“把script标签放body底部”来做就够了,简单、直观、不容易出错。

4.2 表单验证:第一道门槛

第二个我觉得特别适合练习的交互是表单验证。比如做一个简单的留言表单,用户必须填写昵称,邮箱格式要合法,否则点击提交时就给出提示。

const form = document.querySelector('#contactForm'); form.addEventListener('submit', function (event) { const nickname = document.querySelector('#nickname').value.trim(); const email = document.querySelector('#email').value.trim(); if (nickname === '') { alert('昵称不能为空'); event.preventDefault(); return; } if (!email.includes('@')) { alert('请输入有效的邮箱地址'); event.preventDefault(); } });

这一段代码里有两个关键知识点值得琢磨。

第一,event.preventDefault()用来阻止表单的默认提交行为。表单本来就有一个“提交后刷新页面”的默认动作,如果不阻止,页面会刷新,你的校验结果看不到。这是实践里几乎必用的API。

第二,value.trim()会把用户输入内容前后的空格去掉。实际开发中经常要处理数据格式化,因为用户输入是难以预测的,老老实实做校验是基本功。

表单验证做完之后,这个页面就有了“被使用”的感觉,它不再是一张死静的纸,而是一个能响应用户操作的小工具。

4.3 控制台调试与常见错误

写JavaScript一定会写错,报错并不可怕,可怕的是不知道怎么看错。我最建议的做法是:在代码里多打印console.log,把关键变量的值打出来看看。

比如按钮点击后没反应,就先在事件处理函数第一行写一个console.log('clicked'),刷新页面、点击按钮、打开控制台,如果控制台没有输出,说明这个事件根本没绑定上,问题可能在选择器、可能在校验失败提前return了。如果有输出但页面没变化,那说明是后面的赋值逻辑出了问题。

新手常见的JavaScript报错大概有这么几种:

  • Cannot read property 'addEventListener' of null:选择器没匹配到元素,通常是id写错,或者脚本执行时元素还没加载出来。
  • is not defined:变量名写错了,大小写不一致也会触发。
  • Unexpected token:语法错误,少了一个括号或引号。

这几个报错的共同排查思路都是打开控制台看报错行号,点那个文件名和行号的链接,直接跳转到Sources面板对应位置,光标就停在报错的那一行,修改起来非常快。

5. 部署上线:从本地文件到公网访问

5.1 域名、服务器、解析:三者关系

本地页面做得再漂亮,也只有你自己能看。要让别人通过网址访问,至少需要两样东西:服务器和域名。

服务器就是一台24小时开机的远程电脑,把网站文件放到这台机器的指定目录里,别人访问时,这台机器就把文件发给访问者。域名则是人容易记的地址。记忆它们的关系,可以这样类比:服务器是一栋房子,域名是房子的门牌号,DNS解析就是“找这栋房子在哪个位置”的查询过程。

用户输入域名后,浏览器先向DNS服务器查询这个域名对应哪台服务器的IP地址,拿到IP后,再向服务器发起请求。所以流程是:购买域名 → 购买服务器 → 把DNS解析指向服务器IP → 把文件放到服务器 → 访问。

买服务器时,我自己的经验是新手先买最基础配置的云产品就够用了,博客、个人介绍页这种流量级别,低配置完全能扛住。操作系统建议选常见的Linux发行版,虽然命令行第一次接触会有点怕,但跟着一步步来完全没问题。

5.2 用宝塔面板快速部署静态网站

如果直接面对Linux命令行,很多新手会崩溃。我自己第一次配置Nginx时也是各种退缩。后来用上宝塔面板,相当于给服务器装了一个可视化操作界面,建站点、配域名、开HTTPS都是点几下鼠标的事,对新手极其友好。

拿到一台全新的云服务器后,在主流的云厂商控制台里重装系统,选择一个带宝塔面板的镜像,或者装好系统后去官网拿一键安装脚本,都能用。

安装完成后,在面板里找到“网站”菜单,点击“添加站点”,把你的域名填进去,PHP版本选择“纯静态”。宝塔会自动生成站点目录,一般是/www/wwwroot/你的域名,并且自动配好一份最简单的Nginx配置。

接着把本地项目文件夹里的所有文件,通过文件管理或SFTP工具上传到站点目录。上传完成后,index.html就位于站点目录的根目录下。

这时候访问你的域名,如果能看到页面内容,说明整个链路已经通了。我记得我当时第一次在浏览器里输入自己域名、看到页面加载出来时,那种激动难以形容——本地文件变成公网可访问的网站,就是这么一套流程。

5.3 HTTPS证书:从HTTP到加密连接

刚部署完的网站,URL开头通常是http://。现在浏览器的地址栏会直接显示“不安全”的提示,一方面观感不好,另一方面HTTP传输内容是明文,用户提交的数据可以被中间人截获。让网站升级为https://,需要部署SSL证书。

证书不一定非要去各大服务商花钱买,现在有完全免费的证书可以申请。宝塔面板里就有这个功能:在“网站”设置里找到“SSL”菜单,选择“Let‘s Encrypt”,填好邮箱,点击申请,面板会自动把证书配置好并开启HTTPS。

申请证书之前要先确认域名的DNS解析已经生效,因为证书签发机构需要验证你对域名的所有权。整个流程如果顺利,一两分钟就完成。部署好之后会拿到一个30天有效期的证书,宝塔面板可以设置自动续签,基本不需要再操心。另外有备案要求的服务器,记得按服务商指引完成主体信息登记流程,不同地区规则有差异,以你的服务器和域名服务商提示为准。

5.4 上线前的基础安全自查

网站上线后面向公网,就暴露在攻击者视野里了。我不建议新手被安全问题吓到,但基础的自我检查还是应该做到位,我整理了一个极简清单:

  • 修改SSH登录端口,不要用默认的22端口。
  • 设置高强度密码,最好用长短句加符号组合。
  • 关闭服务商控制台里不必要的外网端口,只保留80和443。
  • 宝塔面板设置访问白名单,只允许自己的IP访问管理面板。
  • 定期在服务器上执行系统更新和面板更新命令。

这个清单不需要一次全做完,但每一项都花不了几分钟,却能把大多数自动化扫描攻击挡在外面。网站上线是漫长的升级打怪,安全意识和习惯越早培养越好。

6. 第一次上线后,我踩过的坑与排查思路

6.1 图片全部挂掉:相对路径的锅

我上线第一个网站后,打开首页发现正文能正常显示,但所有图片都变成裂图。我第一反应是“图片上传漏了”,检查服务器文件后发现图片都在。后来打开浏览器Network面板,看到图片请求的全是类似www.example.comcss/../images/photo.jpg这种错误的URL,才意识到是路径写错了。

原因是这样:我的CSS文件放在css/目录下,图片路径写在CSS里的background-image: url('images/photo.jpg'),但CSS文件里的相对路径是相对于CSS文件所在位置的,不是相对于HTML所在位置的。所以正确写法应该是url(‘../images/photo.jpg’),表示从css/目录向上跳一级找到images目录。

排查链路其实很清晰:F12打开Network,找到那个红色404的请求 → 看它的完整URL → 对比实际文件在服务器上的路径 → 修改CSS或HTML里的引用路径。遇到图片裂图,按这个顺序做,基本都能解决。

6.2 网站打不开,先查端口和防火墙

有一次我把网站文件都传上去了,域名解析也生效了,但访问时浏览器转圈半天,最后提示无法访问。我当时满脑子都是“是不是Nginx配置错了”,在Nginx配置文件里翻来覆去改,完全没用。

后来请教别人才知道,问题根本不在Nginx。云服务器通常有两道防火墙:服务器系统自带的防火墙和云厂商控制台里的“安全组”。默认情况下,安全组只放行了22端口(SSH),80和443端口根本没放开,外部的HTTP请求根本到达不了Nginx。

排查思路是:先在服务器上用curl localhost看本机有没有正常返回页面,如果本机返回正常,说明Nginx没毛病。再在本地的电脑上ping一下域名看IP通不通,接着用在线端口检测工具测一下80端口是否开放。发现80端口没开,就去云服务商控制台的安全组规则里添加入方向规则,放行TCP 80和443。点了保存之后刷新页面,网站立刻就能打开了。

这个经验特别值得记下来,因为80端口没开放这个问题极其隐蔽,新手很容易在Nginx配置上白折腾半天。

6.3 CSS文件加载失败:路径、MIME与缓存

另一个典型问题是HTML能打开,但页面完全没有样式。看到这种状况,第一个想法应该也是去看Network面板,看CSS文件请求返回的是什么状态。

如果状态是404,就是CSS文件路径写错了;如果状态是200,但页面依旧没有样式,就要看Response Headers里的Content-Type,如果返回的不是text/css,而是一串application/octet-stream,说明Nginx没有正确识别文件类型。这多半是Nginx的mime.types模块没配置好的问题,在配置文件的http块里引入include mime.types;就能解决。

还有些时候,CSS文件更新了,但浏览器打开还是旧样式,这是缓存机制在起作用。按Ctrl+F5做强制刷新通常能解决,也可以让Nginx对静态文件设置相对短的缓存时间,开发调试阶段省去很多烦恼。我调试页面时十次里有七八次是清了缓存就“灵”了,这点很值得放在心里。

6.4 移动端样式乱掉的常见原因

手机访问网站发现页面布局错乱,是最让新手崩溃的问题之一。我在移动端踩的最大的坑是忘了加视口标签。如果没有<meta name="viewport" content="width=device-width, initial-scale=1.0">,手机浏览器会默认按980像素宽度渲染桌面页面,然后整个缩放,字变得特别小,用户需要放大才能看清。

加上视口标签之后,页面就能按手机实际宽度来布局了。再往后一步就是写媒体查询,根据屏幕宽度应用不同样式:

@media (max-width: 600px) { .cards { flex-direction: column; } }

这段代码的意思是:当屏幕宽度小于等于600像素时,卡片由横向排列改为纵向堆叠。移动端适配是个大话题,但对第一个网站来说,加上视口标签、把图片设置为max-width: 100%、尝试用弹性盒布局,这三个动作做完,页面在手机上就已经像模像样了。

6.5 从访问日志读懂访问者的行为

网站上线后,很快就会有各种访客。宝塔面板提供访问日志功能,能记录每个到访请求的IP、时间、请求路径、状态码、User-Agent等。我第一次打开日志文件时根本看不懂里面那些数字是什么意思,后来才慢慢学会只看几个关键状态码:

状态码含义常见场景
200请求成功正常访问
304未修改,命中缓存浏览器使用本地缓存
404页面不存在路径错误或文件缺失
403禁止访问权限不对或IP被拦截
500服务器内部错误后端代码异常或配置错误

看懂状态码,是排查网站问题的基础能力。比如某天你想去看某个页面,结果日志里全是404,那基本可以确定是链接或路径出了问题;如果某个目录下面出现大量403,可能要考虑目录权限设置是否太严格了。

我后来养成了一个习惯:每次部署新版本网站后,都会去日志里筛一下自己这个IP的请求记录,确认首页状态码是200、CSS和JS文件都是200,才算真正部署成功。

最后的几句实在话

做完第一个网站,我最大的收获其实不是学会了HTML标签或者CSS属性,而是完整走通了“想法 → 代码 → 真实可访问的网址”这条链路。这个过程中最大的障碍不是技术,而是那种“不知道下一步该做什么”的焦虑。所以我把每一个环节的坑提前标记出来,就是想让你在卡住的时候知道往哪个方向查。

再说一个我后来才明白的小技巧:不用因为自己的第一个网站简陋而觉得不好意思,更不要一开始就追求“炫酷”的设计和技术。能把一个白底黑字的页面稳稳地部署到公网、在手机上也能正常打开,就已经比大多数停留在“想想”阶段的人走得远了极多。完成永远比完美重要,这个道理放在做网站上,再合适不过了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询