JavaScript 프록시 Fetch API

13194 단어 webdevjavascript
계속해서 Google에서 JavaScript 프록시를 검색하면 핵심 개념을 설명하는 많은 기사를 볼 수 있습니다.

그러나 거의 아무도 말하지 않는 강력한 것이 하나 있습니다.
그 한 가지는 다음과 같습니다.

프록시를 사용하여 기존 API를 덮어쓸 수 있습니다!

나는 그것이 의미가 있다는 것을 압니다. 객체, 배열 또는 함수를 확장할 수 있으므로 논리적입니다. 그러나 프록시 개체를 사용한 실제 예를 들어 설명하겠습니다.

프록시로 Fetch API 확장



URL에 대한 요청을 효율적으로 수행하는 기본 래퍼인 Fetch API 에 대해 들어 보셨을 것입니다.

앱에 모든 API 호출을 처리하는 파일이 있고 모두 Fetch API를 사용한다고 가정해 보겠습니다.

예를 들어, Todos에 대한 API 호출을 처리하기 위해 다음 클래스가 있습니다.

class TodoAPI {
  getTodos = async () =>
    await fetch('https://jsonplaceholder.typicode.com/todos');
  getTodo = async (id: number) =>
    await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`);
}


이를 사용하려면 다음 코드를 사용할 수 있습니다.

const API = new TodoAPI();

(async () => {
  await API.getTodos()
    .then((data) => data.json())
    .then((res) => console.log(res));
  console.log('Fetching single TODO');
  await API.getTodo(3)
    .then((data) => data.json())
    .then((res) => console.log(res));
})();


미친 건 아직 없습니다. 가져오기 요청을 사용하는 API 미들웨어를 호출할 수 있습니다.

이 코드는 우리 웹사이트에서 완벽하게 작동하지만 Chrome 확장 프로그램에 도입할 때 가져오기 메서드를 직접 사용할 수 없다는 것을 금방 알아차립니다.
CORS 문제는 다른 웹사이트에 주입할 때 이를 차단하고 있습니다.

여전히 모든 Fetch 요청 데이터를 수락해야 하지만 백그라운드 작업자를 통해 전송해야 합니다.

따라서 한 가지 아이디어는 작동할 수 있는 Fetch API를 모방하는 새로운 기능을 만드는 것입니다.
그러나 Fetch API가 소품을 변경하면 어떻게 됩니까?

따라서 이 문제를 해결하는 더 좋은 방법은 프록시 개체를 활용하는 것입니다!

예, Fetch API를 프록시할 수 있습니다.

매우 간단한 예에서는 다음과 같습니다.

(async () => {
  const fetchHandler = {
    apply(target, thisArg, args) {
      console.log(args);
    },
  };

  const proxiedFetch = new Proxy(fetch, fetchHandler);

  await proxiedFetch('https://jsonplaceholder.typicode.com/todos/3')
    .then((data) => data.json())
    .then((res) => console.log(res));
})();


여기서 무슨 일이 일어나는지 봅시다.
적용 트랩에 액세스하는 프록시 처리기를 만듭니다.
그런 다음 요청을 수행하는 대신 인수를 기록합니다.

그런 다음 가져오기 기능을 프록시하고 핸들러를 적용합니다.
그런 다음 표준 Fetch API로 사용할 수 있습니다!

이것에 대한 멋진 부분은 모든 Fetch 인수가 동일하게 유지되므로 기존 구현 형식을 변경할 필요가 없다는 것입니다.

이제 이를 일반 가져오기와 프록시 가져오기 사이를 전환할 수 있는 함수로 이동해 보겠습니다!

먼저 우리가 사용해야 하는 가져오기 방법을 정의할 생성자를 클래스에 도입해야 합니다.

constructor(fetchMethod = (...args) => fetch(...args)) {
    this.fetchMethod = fetchMethod;
}


이 함수는 모든 인수를 사용하여 가져오기 메서드를 설정할 수 있습니다. 기본적으로 fetch 로 설정합니다.

그런 다음 선호하는 가져오기 방법을 사용하도록 기존 호출을 수정할 수 있습니다.

getTodos = async () =>
  await this.fetchMethod('https://jsonplaceholder.typicode.com/todos');


보시다시피 별로 달라진 것이 없습니다. 우리는 fetch.this.fetchMethod.로 옮겼고 모든 소품과 콜백은 동일하게 유지됩니다.

그러나 예제에서는 여전히 일반 old 가져오기를 사용합니다.

사용자 지정 프록시 가져오기를 사용하도록 새 버전을 설정해 보겠습니다.

const proxyFetch = {
  apply(_, __, args) {
    console.log(args);
    return { message: 'proxy done' };
  },
};
const proxiedFetch = new Proxy(fetch, proxyFetch);

const API = new TodoAPI(proxiedFetch);

(async () => {
  await API.getTodos().then((res) => console.log(res));
  console.log('Fetching single TODO');
  await API.getTodo(3).then((res) => console.log(res));
})();


우리는 콘솔이 모든 요청을 기록한 다음 완료되었음을 반환하는 새로운 프록시 가져오기를 생성합니다.

그런 다음 이 프록시된 가져오기 버전을 클래스에 전달하여 이 버전을 사용하도록 합니다.

이 CodePen에서 자유롭게 사용해 보십시오. 프록시된 가져오기를 전달하거나 비워 둘 수 있습니다.



백그라운드 작업자 예



확장에 대한 백그라운드 작업자 예제를 설명했으며 브라우저 런타임 메시지를 통해 수신하는 모든 요청을 보내도록 가져오기 요청을 조롱합니다.

코드는 다음과 같습니다.

const proxyFetch = {
  apply(_, __, args) {
    browser.runtime.sendMessage({
      type: 'FETCH_REQUEST',
      url: args[0],
      args: args[1],
    });
    return null;
  },
};

export const proxiedFetch = new Proxy(fetch, proxyFetch);


보시다시피 본문에서 본 것과 비슷한 개념입니다.
기존 가져오기 방법을 프록시하지만 실행하는 것을 덮어씁니다.
이 예제에서는 브라우저 런타임에 메시지를 보냅니다.

결론



프록시 개체를 사용하면 예를 들어 Fetch API와 같은 기존 API를 프록시할 수 있습니다.

이것은 우리가 전체 함수를 조롱할 필요가 없고 우리가 필요로 하는 것을 프록시하기 때문에 매우 강력해질 수 있습니다.

읽어주셔서 감사합니다. 연결해 봅시다!



제 블로그를 읽어주셔서 감사합니다. 내 이메일 뉴스레터를 구독하고 Facebook에 연결하거나

좋은 웹페이지 즐겨찾기