
axiosのadapterを使う機会があり、仕組みが気になったのでメモしておく。
github.com
adapterで検索をかけると、lib/core/dispatchRequest.jsの51行目の記述が目についた。
axios/dispatchRequest.js at 7821ed20892f478ca6aea929559bd02ffcc8b063 · axios/axios · GitHub
var adapter = config.adapter || defaults.adapter; return adapter(config).then(function onAdapterResolution(response) { ...
dispatchRequest.jsは名前からも、lib/core/Axios.jsで使われていることからも、実際にリクエストを送る部分であろう。
まずはdefaults.adapterがなんなのかを調べると、lib/defaults.jsに以下の記述があった。
axios/defaults.js at 7821ed20892f478ca6aea929559bd02ffcc8b063 · axios/axios · GitHub
axios/defaults.js at 7821ed20892f478ca6aea929559bd02ffcc8b063 · axios/axios · GitHub
function getDefaultAdapter() { var adapter; if (typeof XMLHttpRequest !== 'undefined') { // For browsers use XHR adapter adapter = require('./adapters/xhr'); } else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') { // For node use HTTP adapter adapter = require('./adapters/http'); } return adapter; } ... var defaults = { adapter: getDefaultAdapter(), ....
typeof XMLHttpRequestをchromeのコンソールで調べると以下のようになったので、adapter = require('./adapters/xhr');の元を見にいった。
typeof XMLHttpRequest "function"

lib/adapters/xhr.jsでは、XMLHttpRequestを使ってリクエストが送られていた。
axios/xhr.js at 7821ed20892f478ca6aea929559bd02ffcc8b063 · axios/axios · GitHub
axios/xhr.js at 7821ed20892f478ca6aea929559bd02ffcc8b063 · axios/axios · GitHub
axios/xhr.js at 7821ed20892f478ca6aea929559bd02ffcc8b063 · axios/axios · GitHub
var request = new XMLHttpRequest(); ... request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true); ... // Send the request request.send(requestData);
つまり、axiosをadapterオプションを指定せずに使うと、内部的にはXMLHttpRequestを使った通信が行われ、adapterオプションを指定すると、通信そのものをラップできることが分かる。
オプションの反映はlib/core/mergeConfig.jsを使って行われていることが分かったが、深追いはせずテストコードを眺めるだけに留めた。
axios/mergeConfig.spec.js at main · axios/axios · GitHub
実際にadapterオプションを書いて使ってみた。
この場合リクエストは発生せず、実装したPromiseが返っている。
const axios = require("axios"); const sampleAdapter = () => { return new Promise((resolve, reject) => { resolve({ data: "sample data" }); }); }; axios({ url: "https://example.com/", adapter: sampleAdapter, }).then((res) => console.log(res.data));
$ node index.js sample data
リクエストを送る部分はlib/core配下にあるものだと思っていたので、adapterオプションを指定しない場合にlib/adapters配下のコードが使われているのが意外だった。
追記:
axiosにPR投げてみたらlib/adapters配下のコードが使われているという理解はあっていた。
github.com