こんにちは、CX事業本部 IoT事業部の若槻です。
DevelopersIOの記事執筆を効率化させることに日々余念が無い今日この頃なのですが、このたびその一環としてDevelopersIOの指定のページが既に存在しているかをスクリプトで判定させる必要が生じました。
そこで今回は、DevelopersIOの指定のページが存在しているかをNodejsで判定する方法を確認してみました。
やってみる
モジュールはAxiosを使用しました。
npm i axios
ページが存在することを確認する
指定のURLの記事ページが存在することを確認してみます。そこで下記のスクリプトを作成しました。
check_status.js
const axios = require('axios');
const TARGET_URL = process.argv[2];
const main = async (targetUrl) => {
const response = await axios.get(targetUrl)
console.log(response.status);
};
main(TARGET_URL);
記事ページが存在するURL`https://dev.classmethod.jp/articles/cm_hikkoshi/`を指定してスクリプトを実行すると、ステータスコード`200`が取得でき、**指定のURLのページが存在すること**が確認できました。
# ページが存在するURLを指定
$ node check_status.js https://dev.classmethod.jp/articles/cm_hikkoshi/
200
ページが存在しないことを確認する
指定のURLの記事ページが存在しないことを確認してみます。
記事ページが存在しないURL`https://dev.classmethod.jp/articles/sonna-page-ha-nai/`を指定してスクリプトを実行すると、実行がエラーとなりました。AxiosではレスポンスがBAD REQUESTの場合は実行が失敗するようです。
# ページが存在しないURL
$ node check_status.js https://dev.classmethod.jp/articles/sonna-page-ha-nai/
/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/devio/node_modules/axios/dist/node/axios.cjs:1268
reject(new AxiosError(
^
AxiosError: Request failed with status code 404
at settle (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/devio/node_modules/axios/dist/node/axios.cjs:1268:12)
at Unzip.handleStreamEnd (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/devio/node_modules/axios/dist/node/axios.cjs:2446:11)
at Unzip.emit (node:events:539:35)
at endReadableNT (node:internal/streams/readable:1345:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
code: 'ERR_BAD_REQUEST',
(中略)
}
}
そこでTry/Catchをするように下記の通りスクリプトを修正します。
check_status.js
const axios = require('axios');
const TARGET_URL = process.argv[2];
const main = async (targetUrl) => {
try {
const response = await axios.get(targetUrl)
console.log(response.status);
} catch (error) {
console.log(error.response.status);
}
};
main(TARGET_URL);
改めて記事ページが存在しないURLを指定してスクリプトを実行すると、ステータスコード404
が取得でき、指定のURLのページが存在しないことが確認できました。
$ node check_status.js https://dev.classmethod.jp/articles/sonna-page-ha-nai/
404
リダイレクトに対応させる
さて、DevelopersIOのサイトの仕様として、リクエストされた記事ページのURLが存在しない場合はslugを自動補完してリダイレクトを行うようになっています。
例えば、`https://dev.classmethod.jp/articles/classmethod/`は、`https://dev.classmethod.jp/articles/classmethod_i_have_returned/`にリダイレクトされる動作となります。
上記のリダイレクトされるURLを指定してスクリプトを実行すると、ステータスコード200
が取得されてしまいました。期待値としてはリダイレクトされたことが分かる301
が取得されて欲しかったのですが出来ていません。
# リダイレクトされるURL
$ node check_status.js https://dev.classmethod.jp/articles/classmethod
200
そこで対処方法を調べたところ、AxiosではRequest ConfigのmaxRedirects
を0
とすることにより、リダイレクトを抑制できるとのこと。
//
maxRedirects
defines the maximum number of redirects to follow in node.js. // If set to 0, no redirects will be followed. maxRedirects: 21, // default
そこでスクリプトを下記の通り修正します。
check_status.js
const axiosBase = require('axios')
const axios = axiosBase.create({
responseType: 'json',
maxRedirects: 0
})
const TARGET_URL = process.argv[2];
const main = async (targetUrl) => {
try {
const response = await axios.get(targetUrl)
console.log(response.status);
} catch (error) {
console.log(error.response.status);
}
};
main(TARGET_URL);
改めてリダイレクトされるURLを指定してスクリプトを実行すると、ステータスコード301
が取得でき、指定のURLのページが存在しないこと(リダイレクトされること)が確認できました。
$ node check_status.js https://dev.classmethod.jp/articles/classmethod
301
おわりに
DevelopersIOの指定のページが存在しているかをNodejsで判定する方法を確認してみました。
今回の検証により、3XX
と4XX
の時は存在していないという判定を行うことができそうです。
参考
- axios でリダイレクトをフォローしない | roundrop - implements Programmable
- Node.jsでAysnc/Awaitを使ってHTTPリクエストを行う5つの方法 by Sam Agnew
以上