차세대 프로그레시브 웹 프레임 워크 인 http 컨테이너 [아래] 필기

"위의를 수행하는 HTTP에 컨테이너 [최고] 의사 결정 트리를 필기 및 라우팅 테이블을 "


  • 정적 파일 호스팅 : URL 경로가 FS 경로에 매핑 됨

웹 백엔드에서 가장 일반적으로 사용되는 기능 중 하나는 정적 파일, 즉 서버에 저장된 읽기 전용 파일의 호스팅이며 프런트 엔드에서 자유롭게 다운로드 할 수 있습니다. 이를 달성하는 가장 직접적인 방법은 URL의 경로와 파일 시스템의 경로를 일대일로 매핑하여 URL을 통해 하위 디렉터리의 파일을 포함하여 폴더의 다른 파일을 다운로드 할 수 있도록하는 것입니다.

좀 더 "관대 한"정적 호스트를 만들려면 프런트 엔드가 디렉터리를 요청할 때 디렉터리의 모든 내용을 나열 할 수 있습니다.이 경우 경우에 따라 프런트 엔드 응용 프로그램을 강화할 수 있습니다. 이 두 기능을 기반으로 제가 디자인 한 정적 파일 미들웨어 코드는 다음과 같습니다 (nodejs).

// 静态文件中间件的伪代码


const path = require("path");
const fs = require("fs");
const { Readable } = require("stream");
// this代表对等体的生命周期;global是全局作用域
const req = this.request;
const res = this.response;
const cfg = global.config;


// path/to/public/是FS中被托管的文件夹路径
// req.staticPath是从url中提炼出来的文件的相对路径
const absPath = path.join(__dirname, "path/to/public/", req.staticPath);
const isFile = await new Promise((resolve, reject) => {
  fs.stat(absPath, (err, stats) => {
    if (err) reject(err);
    else if (stats.isFile()) resolve(true);
    else if (stats.isDirectory()) resolve(false);
    else reject(`${req.url}既不是文件也不是文件夹!`);
  });
});


// 根据文件后缀名判断mime类型
const suffix = isFile ? path.extname(req.url) : "directory";
res.setHeader(
  "Content-Type",
  {
    ".js": "text/javascript; charset=UTF-8",
    ".wasm": "application/wasm",
    ".html": "text/html",
    ".css": "text/css",
    ".png": "image/png",
    directory: "text/plain; charset=UTF-8"
  }[suffix] || "application/octet-stream"
);
// 利用浏览器的古典缓存机制
res.setHeader("Cache-Control", `public, max-age=${cfg.cacheInSec}`);
res.setHeader("ETag", cfg.version);


let r;
if (isFile) {
  r = fs.createReadStream(absPath);
} else {
  // 如果请求的是目录,则构建一个虚拟流来读取目录下的所有内容
  r = new Readable({
    read() {}
  });
  fs.readdirSync(absPath)
    .map(name => path.join(req.staticPath, name))
    .forEach(pa => r.push(pa + "\n"));
  r.push(null);
}
if (!res.headerSent) res.writeHead();


await new Promise((resolve, reject) => {
  r.on("error", err => reject(err));
  r.on("end", resolve);
  r.pipe(res);
});


의사 코드는 매우 간단하고 중복 된 설명이 없습니다. 결과는 다음과 같습니다. 파일을 가져 오기 위해 파일 요청, 줄 바꿈으로 구분 된 디렉터리의 모든 리소스에 대한 상대 경로 목록을 가져 오기위한 디렉터리 요청, 요청 된 리소스가 존재하지 않으면 현재 라우팅 포인트에서 throw됩니다. 예외가 발생했습니다. 라우팅 트리의 모든 지점에서 예외가 발생할 수 있으므로 통합 오류 처리 메커니즘이 필요합니다.


  • 오류 처리 메커니즘 및 사용자 지정 http 헤더

매우 간단합니다. 전체 비동기 의사 결정 트리의 끝에서 예외를 포착하지만 오류 시점이 응답 스트림에 있는지 여부를 고려해야합니다. 응답이 전송되지 않은 경우 오류 메시지를 내용으로 프런트 엔드에 보낼 수 있습니다. 응답이 이미 전송되었거나 전송중인 경우 백 엔드는 전송 된 사실을 변경할 수 없으며 프런트 엔드에 오류 메시지를 알릴 수 없습니다. 오류 메시지는 로그 시스템에 의해 요약 될 수 있습니다.

http / 2.0 스트림은 소켓에서 추상화 된 메커니즘이며 스트림의 내용은 헤더가 아닌 http 본문입니다. http 헤더는 흐름의 수명주기를 제어하는 ​​데 사용됩니다. 즉, 요청 및 응답 개체는 헤더가 전달 된 후에 만 ​​나타납니다.

따라서 오류는 발생 시점에 따라 응답 전과 응답 후의 두 가지 범주로 나눌 수 있습니다. 응답이 전송되지 않은 경우 my-error와 같은 http 헤더의 사용자 정의 필드에 오류 메시지를 작성하는 것이 좋습니다. 응답이 전송 된 경우 오류 메시지는 다른 곳에 저장됩니다.

// 决策树错误处理的伪代码


module.exports = async error => {
  const message = error.message || error || "有内鬼,终止交易";


  //   判断response是否已经发出
  if (this.response.headersSent) {
    //   将message存入假想的日志系统
    await require("path/to/logger").add(message);
  } else {
    this.response.writeHead(400, {
      "Content-Type": "text/html; charset=utf-8",
      "my-error": encodeURIComponent(message)
    });
    this.response.end(`<h1>${message}</h1>`);
  }
};


의사 코드에서 :

  • 로거 로그 시스템을 사용하는 이유는 관리자가 확인할 수 있도록 오류 메시지를 로그 파일에 저장하기 위해서입니다.

  • 메시지가 http 헤더에 기록되는 이유는 프런트 엔드가 미리 (스트림 시작 전) 처리 할 수 ​​있도록하기 위해서입니다.

  • URI 인코딩을 사용하는 이유는 http 헤더에 쓰기 위해 유니 코드 문자를 ASCII로 인코딩 할 수 있도록하기 위함입니다.

  • 메시지가 http 본문에도 작성되는 이유는 오류 링크를 직접 열 때 사용자가 오류 메시지를 보지 못하도록하기 위함입니다.


  • 본문 파서 및 콘텐츠 길이 헤더

일반적인 백엔드 프레임 워크에는 bodyParser와 같은 내장 된 본문 파서가 있으며 우리는 직접 작성합니다.

진행률 표시 줄을 디자인하는 가장 좋은 방법은 첫 번째 패킷에 전체 리소스의 크기를 지정하는 것입니다. 프런트 엔드는 전송 된 트렁크 수에 따라 진행률을 계산합니다. 안타깝게도 처음에 리소스의 크기를 알 수없는 경우에는 이것이 마지막 인 경우 각 청크 옆에 쓰십시오. 물론 추가 공간 오버 헤드가있을 것입니다.

http / 2.0의 디자인도이 두 가지 상황을 고려하여 내용 길이 필드를 제공했습니다. 의사 코드는 공개되지 않으며 body와 기타 미들웨어의 구문 분석이 동시에 수행되므로 request.body가 약속입니다.

------------------------ 불규칙 분할 선 -------------------- ---


  • 차세대 프로그레시브 웹 프레임 워크 : FetchMe.js

물론 아직 고려되지 않은 것들이 많이 있지만, 이것이 우리가이 프레임 워크에 들리는 이름을 부여하는 것을 막지는 않습니다. http의 기능이 "가져 오기"라면 백엔드를위한 "가져 오기"입니다. 매우 생생합니다.

fetchme.js는 일련의 고급 웹 개발 개념을 통합하는 차세대 스캐 폴드 인 ALFP 프로토콜을 기반으로하는 진보적 인 웹 프레임 워크입니다. 현재의 돈은 부족하지만 파트너는 미정이고 일시적으로 코드를 사용할 수 없게되어 이론적 근거와 fetchme의 이름이이 기사에서 미리 정해져 있습니다. 이러한 이론을 바탕으로 일반적인 웹 프레임 워크가 될 수 없더라도 적어도 특정 애플리케이션을 구현하는 앱은 구축 할 수 있습니다. , 블로그 프레임 워크와 같은.

(끝)


추천

출처blog.csdn.net/github_38885296/article/details/104132233