Zhonghui

每个不曾起舞的日子,都是对生命的辜负

User Tools

Site Tools


程序:计算机网络:web开发共通基础

Web开发共通基础

url

scheme://user:password@host:port/path?query#fragment

# 一个具体的例子
https://user:pass@www.example.com:8080/api/v1/users/?page=2&limit=10#info
部分 作用 举例
1. scheme(协议) 指定使用的协议,告诉浏览器怎么访问资源 http / https / ftp
2. user:password(可选) 用户名和密码,通常用于基本认证(不常用) user:pass@
3. host(主机名或IP) 服务器地址,域名或 IP www.example.com / 127.0.0.1
4. port(端口号,可选) 服务器端口号,省略时用默认值 :80(HTTP) / :443(HTTPS)
5. path(路径) 服务器资源路径(路由) /api/v1/user/
6. query(查询参数) 传递给服务器的参数,键值对形式 ?page=2&limit=10
7. fragment(锚点) 客户端页面内定位,服务器不解析 #section3

一般来说:在做backend开发的时候,和 URL 匹配真正相关的,只有「路径(path)」这一部分

使用Vue.js等前端框架开发单页应用的时候,因为是前后端分离,所以实际上在浏览器地址栏的url是不会发送给服务器的

跨源资源共享(CORS)

个人的简单理解:

  1. 浏览器从www.a.com获取前端代码
  2. 前端程序向api.a.com请求数据
  3. 浏览器认为:从www.a.com获取的代码要向另一个域名(api.a.com)发送请求,不安全
  4. 浏览器先向api.a.com发送OPTION请求预检
  5. api.a.com应该返回信息告诉浏览器:请相信www.a.com的代码,它可以安全向我发送请求
  6. 浏览器预检OK后,才允许前端js向api.a.com发送请求

可以看出:

  1. 这个机制由浏览器「自觉」执行,如果使用不安全的浏览器、被篡改过的浏览器,预检是可能会被跳过的
  2. 能不能被其他域名的前端代码请求是server(后端API)决定的,所以写后端的时候要指定「白名单」

其他补充:

  1. 域名不同的定义:域名不完全匹配(只有顶级域名匹配是不够的)或端口不同(协议不同算不算?待确认)确认结果:完全相同的【协议(scheme)】、【主机名(hostname)】、【端口(port)】,才算同源,否则视为跨域
  2. 与【同源】相比,还有一个更宽松的概念【“Same‑Site”(同站)】

前端需要做什么?
客户端无需手动发起“检查跨域是否可用”的请求——浏览器会根据请求内容自动判断是否需要进行 CORS Preflight(预检)请求。

后端大概的处理逻辑可能这样:

// 后端并不需要、也不应该返回整个白名单
// 只需判断请求来源是否在白名单里,如果是,就回显该来源,否则不返回 Access-Control-Allow-Origin
const whitelist = [/* 完整 origin 列表 */];
const origin = req.headers.origin;
if (whitelist.includes(origin)) {
  res.setHeader('Access-Control-Allow-Origin', origin);
  res.setHeader('Access-Control-Allow-Credentials', 'true');
  // 其他 CORS 头...
}

后端的返回内容可能类似这样:

Access-Control-Allow-Origin: https://www.front.example.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Vary: Origin

参考资料

API风格

  1. GraphQL:客户端可以明确请求所需字段、单个请求即可获取嵌套资源(避免 REST 中的多次请求);服务端实现复杂

认证

前提:我们确保HTTPS是安全的,可以发送一些敏感信息(密码、Token之类的)。虽然应该尽量减少发送次数,或者避免直接明文发送,但是基于HTTPS发送是没有问题的(否则就无法进行下一步了)。

既然HTTPS是安全的,那么基本上,每次请求都把用户名和密码都带上也可以(不安全,或者说不太安全,但是可行),这就是最基础的认证方式,每次请求都带上用户名和密码。

那么实现认证还有哪些其他思路呢?
1 Cookie,第一次发送用户名密码,通过验证后服务器生成Cookie,然后客户端和服务器都保存,每次请求都发送Cookie,服务器接收到请求信息后,查询数据库,验证此Cookie。缺点:每次都要查询数据库,服务端要记录这个Cookie。优点:服务器可以随时撤销这个Cookie(从数据库中删除)。

2 Token(单个JWTJSON Web Token),第一次发送用户名密码,通过验证后服务器生成Token,Token中包含用户信息(未加密),并且可以验证此Token是否是由服务器生成的,由此,服务器就不用存储Token了,每次接收到请求后,不用查询数据库,也可以判断此Token是否合法。优点:减少了对数据库的访问,适合微服务。缺点:Token一旦生成就不方便撤销了,只能等到Token过期;如果Token泄漏了就不安全了,如果想要实现服务器随时可以撤销Token,就需要记录一个Token的黑名单。

3 Token(两个JWT),客户端发送用户名密码,服务器验证通过后,生成Refresh Token,服务器也要记录此Token,同时发给客户端。客户端将Refresh Token发送给服务器,服务器验证OK后,生成Access Token,此Token有效期很短(几小时),并且服务器不记录。此后,每次请求,客户端会附带上Access Token,服务器也只验证Access Token,如果过期,客户端再重新申请。分析:如果Access Token泄漏,因为有效期比较短,所以可以尽可能得降低风险;如果Refresh Token泄漏,客户端可以请求注销此Token,因为服务器也保存了Token,所以从数据库中删除就可以了。另外,这种做法也降低了访问数据库的请求次数。

4 OAuth 2.0:还在学习中,不是特别理解。
AI:OAuth 2.0 是一个授权协议(Authorization Protocol),它的核心目的是:让用户授权第三方访问自己的资源,而不泄露密码。
看到这种解释,首先想到的是「Login with Google」之类的功能,但是实际上「第三方」也不一定真的是「第三方」:比如同一个公司的多个应用使用相同的账户登录,那么这个账户系统就可以独立出来,其他的应用都被看作是「第三方」(但实际上是同一个公司的产品)。
还是基于Token的认证流程,只不过是流程复杂一些。

5 OpenID Connect(OIDC):学习中

补充
关于认证的信息,一般都会放在HTTP头部中的Authorization字段,比如

Authorization: Bearer <token>

安全

CSRF(Cross‑Site Request Forgery):跨站请求伪造

国际化

  1. i18n 是 “internationalization(国际化)” 的缩写写法:把单词 i 和 n 之间的 18 个字母用数字代替,所以写成 i18n。
  2. l10n(Localization,本地化)
  3. g11n(Globalization,全球化)

前端可用的库:i18next, Vue I18n等

在某些情况下,后端也需要做国际化?

/var/www/DokuWikiStick/dokuwiki/data/pages/程序/计算机网络/web开发共通基础.txt · Last modified: 2025/09/26 16:56 by zhonghui