# 哈佛免费 Web 课，补上 Python FDE 的 JavaScript 短板

> 九周免费课程从 fetch 讲到 React 和 CI/CD，哈佛扩展学院版 90% 的成绩来自项目。

原文: https://fdetimes.net/zh/books-courses/harvard-cs50-web-javascript-python-fdes/

一名 Python 前线部署工程师（FDE）几天内就能搭好数据管道、调用 LLM、接好一个智能体。然后客户说“我来试试”，这时他们需要的是一个网页。不少工程师就卡在这一步。

哈佛的 CS50's Web Programming with Python and JavaScript 是补上这块短板的一条路。课程通过 OpenCourseWare 免费开放，内容共九周，只要求学员已有一门编程语言的经验。

对 FDE 来说，这不是为学而学。能在客户浏览器里跑起来的演示，往往决定一个项目能否继续推进；自己能做，就不必等任何人。

## 这门课到底教什么？

官方页面把 CS50 Web 定位为 CS50x 的后续课程，进一步讲解如何用 Python、JavaScript 和 SQL 设计和构建 Web 应用。技术栈是 Django、React 和 Bootstrap，同时涉及 API 以及 GitHub、Heroku 等云服务。

它的覆盖面超过一般的前端入门课。主题列表还包括数据库设计、可扩展性、安全和用户体验，edX 上的课程介绍也列出了同样的主题。

先修要求是 CS50x 或已有编程经验，所以每天写 Python 的人可以跳过 CS50x，直接开始。九周内容里，有三个思路值得 FDE 重点关注。

## 思路一：JavaScript 是在客户端运行的代码

JavaScript 讲义（2020 版）开篇点明一件简单的事：JavaScript 让代码在客户端，也就是浏览器里运行。对只会 Python 的工程师来说，短板恰恰在这里，因为他们写的一切都跑在服务器或 notebook 里。

讲义常借 Python 学习者熟悉的东西来解释新概念。浏览器的本地存储被描述为一组键值对，很像 Python 的 dict。这一讲还介绍了用于发送 HTTP 请求的 `fetch` 函数，这正是 FDE 每周都在做的集成工作。

假设客户有一个内部 API，返回工单列表，他们想看你的智能体如何给工单分类，并能按状态筛选。一个最简页面只需几行代码：

```javascript
const select = document.querySelector('#filter');
select.value = localStorage.getItem('filter') || 'open';
select.addEventListener('change', () => {
  localStorage.setItem('filter', select.value);
  location.reload();
});

fetch(`/api/tickets?status=${select.value}`)
  .then(response => response.json())
  .then(tickets => {
    tickets.forEach(t => {
      const li = document.createElement('li');
      li.textContent = `${t.title}: ${t.label}`;
      document.querySelector('#list').append(li);
    });
  })
  .catch(err => console.error('无法加载工单', err));
```

第二行在每次打开页面时读回已保存的筛选条件，没有存储值时默认用 `'open'`。用户修改筛选条件后，新值写入 localStorage，页面刷新，筛选条件依然保留。

把这两个操作想成 Python 里的 `filters.get('filter', 'open')` 和 `filters['filter'] = value`，基本就理解了。

## 把客户数据放上页面时的常见错误

最常见的错误是把 API 数据直接赋给 `innerHTML`。只要某个工单标题里含有 `` 标签或 ``，浏览器就会执行它，你的演示就成了客户自己机器上的 XSS 漏洞。不是自己写的数据，一律用 `textContent`。

第二个错误是忽略出错路径。客户内部 API 返回 401 或超时时，空白页面看起来就像产品坏了；加一行 `.catch` 和一条清楚的提示，就能保住整场演示。安全在课程的主题列表里，这部分要细读，不要略过。

## 思路二：别刷新整个页面

User Interfaces 这一讲把学员带到单页应用：只加载一个页面，再用 JavaScript 修改 DOM，而不是每次点击都加载新页面。在此基础上，课程引入 React。这个框架以组件为核心，每个组件有自己的状态，状态变化时 DOM 自动更新。

对做应用 AI 的 FDE 来说，这个模型很适合智能体的聊天界面。状态就是消息列表；智能体每回复一次，就往列表里加一项，React 负责重绘。没有 React，你得手动查找并修改一个个 DOM 节点，客户问到第三个问题时，演示多半就出问题了。

**要点:** 能在客户浏览器里跑起来的演示，比任何 notebook 都有说服力。

## 思路三：测试和 CI/CD 是你的分内事

Testing and CI/CD 这一周，是许多 Web 入门课省略的部分。讲义把 CI/CD，即持续集成（Continuous Integration）和持续交付（Continuous Delivery），解释为软件开发中的一套良好实践。

在客户现场，你留下的代码会在你离开后由别人维护。一套测试加一条自动化流水线，比任何手写文档都更可靠地完成交接。所以这一周应与 JavaScript 那一周同等重视，而不是当作附加内容。

## 按什么顺序学，九周才不白费？

如果已经熟练掌握 Python 和 SQL，第 5 讲之前的内容可以快速过一遍，只在陌生处停下。把省下的时间投入连续三讲：第 5 讲（JavaScript）、第 6 讲（User Interfaces，React 在这里登场）和第 7 讲（Testing, CI/CD）。不要只看视频。

哈佛扩展学院版本 2022 年秋季学期的教学大纲，对五个指定项目和一个期末项目评分，合计占 90%；其余 10% 是小组讨论课的出勤。这套评分属于扩展学院版本，而非免费的 OpenCourseWare 版本，但它说明课程设计者看重的是你亲手做出来的东西。

因此即使学免费版，也要把期末项目当作真正的 FDE 演示来做：Django 后端调用 API，React 前端，测试和 CI 在 GitHub 上运行。简历上写一行具体的描述，比如“构建了集成外部 API 的 Django + React 应用，配有自动化测试和 CI”，再附上仓库链接。

看 FDE 招聘启事时，留意 React、REST API 和 CI/CD 这几个词。如果三者都在你的仓库里，你拿得出的就是具体证据，而不只是一串技能清单。

优秀的 Python 工程师很少缺思路，只是还没把成果搬到客户的屏幕上。花九周时间，从此不必再说“我去问问前端团队”，代价并不大。

**本周动手试试:**

- 读 JavaScript 讲义（第 5 讲），然后写一个 HTML 页面，用 fetch 调用一个公开 API，并用 textContent 把结果显示为列表
- 用 localStorage 保存用户的筛选条件，把它当作 Python dict 来用，并确认刷新页面后筛选条件仍在
- 打开一份你想申请的 FDE 招聘启事，标出 React、REST API 和 CI/CD 这几个词，对照你已经做过的东西

## 信源

- [CS50's Web Programming with Python and JavaScript](https://cs50.harvard.edu/web/)

- [CS50's Web Programming with Python and JavaScript (edX)](https://discover.edx.org/xgs/course/cs50s-web-programming-with-python-and-javascript?hsLang=en)

- [CS50 Web 2020, Lecture 5 notes: JavaScript](https://cs50.harvard.edu/web/2020/notes/5/)

- [CS50 Web 2020, Lecture 6 notes: User Interfaces](https://cs50.harvard.edu/web/2020/notes/6/)

- [CS50 Web 2020, Lecture 7 notes: Testing, CI/CD](https://cs50.harvard.edu/web/2020/notes/7/)

- [CS50 Web Programming with Python and JavaScript, Fall 2022 syllabus](https://cs50.harvard.edu/extension/web/2022/fall/syllabus)
