
做我的第一个网站那年我在虚拟机里折腾了整整一周最后打开网址的那一刻地址栏里跳出来的居然真的是我写的页面那种感觉比考试拿满分还爽。那个页面其实丑得不行白底黑字没有图片图片还因为路径写错挂了一半但对我而言它意味着“我把一个想法变成了一个互联网上真实存在的东西”。这篇文章不打算讲什么高深框架也不准备让读者一上来就动后端、接数据库就老老实实把新手做第一个网站时一定要经历的完整链路拆开本地文件怎么写、怎么调试、怎么部署上线、上线后碰到打不开或样式丢失该怎么排查。只要耐心看完再跟着操作一遍大概率也能拥有自己的第一个网站。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 langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title我的第一个网站/title link relstylesheet hrefcss/style.css /head body h1你好我是新手站长/h1 p这是我的第一个网站。/p script srcjs/main.js/script /body /html!DOCTYPE html是文档类型声明告诉浏览器按现代标准渲染页面。少了它浏览器可能进入“怪癖模式”导致样式表现异常。html langzh-CN声明页面语言是简体中文浏览器翻译插件和阅读器会读取这个属性。head里的内容不会直接显示在页面上它存放页面的元信息字符编码、视口设置、标题、样式引入。meta charsetUTF-8指定编码如果漏掉中文可能会变成乱码。meta nameviewport是移动端适配的重要标签没有它手机浏览器会按桌面宽度渲染页面导致字小得像蚂蚁。title显示在浏览器标签页上也是搜索引擎判断页面主题的重要依据。body里面才是用户能看到的一切。3.2 往页面里放内容标题、段落、图片、链接HTML最常用的内容标签没有多少个搞懂基础的那几个就够了h1到h6是不同层级的标题p是段落a是链接img是图片ul和li是无序列表div和span是通用容器用于配合CSS做布局。这里单独提醒一个新手特别容易“踩坑”的地方图片路径。假设目录里有一张图片放在images/photo.jpg在HTML里引用的标准写法是img srcimages/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端口SSH80和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文件更新了但浏览器打开还是旧样式这是缓存机制在起作用。按CtrlF5做强制刷新通常能解决也可以让Nginx对静态文件设置相对短的缓存时间开发调试阶段省去很多烦恼。我调试页面时十次里有七八次是清了缓存就“灵”了这点很值得放在心里。6.4 移动端样式乱掉的常见原因手机访问网站发现页面布局错乱是最让新手崩溃的问题之一。我在移动端踩的最大的坑是忘了加视口标签。如果没有meta nameviewport contentwidthdevice-width, initial-scale1.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属性而是完整走通了“想法 → 代码 → 真实可访问的网址”这条链路。这个过程中最大的障碍不是技术而是那种“不知道下一步该做什么”的焦虑。所以我把每一个环节的坑提前标记出来就是想让你在卡住的时候知道往哪个方向查。再说一个我后来才明白的小技巧不用因为自己的第一个网站简陋而觉得不好意思更不要一开始就追求“炫酷”的设计和技术。能把一个白底黑字的页面稳稳地部署到公网、在手机上也能正常打开就已经比大多数停留在“想想”阶段的人走得远了极多。完成永远比完美重要这个道理放在做网站上再合适不过了。