url-info-proxy-2
/icons/hr.icon
scrapbox-url-customizer-2で任意のdomainのweb pageのデータを取得するのに必要なGreasemonkey UserScript
TamperMonkeyにコピペしてinstallして下さい
実行するたびに、cross domainへの接続確認画面が表示されます
適宜許可を出してください
確認画面を出さないように設定することも出来ます
url-info-proxyとの違い
外部のserverless functionを使わず、web browserのみで処理が完結する
任意のdomainのdataをfetchする事ができるとわかったので、url-infoを使う必要がなくなりました
Shift-JISなど変な文字コードのweb pageのデータも文字化けせずに取得できる
文字コードを指定してfetchする
使い方
code:js
const data = await fetchURLInfo('https://example.com', {DOM: false});
DOM (optional)
true: 解析したweb pageのDOMを付与する
false (default): DOMを付与しない
返り値
code:ts
type Result = Promise<{
title: string; // web pageのタイトル
encoding: string; // web pageの文字コード
meta: { key: string: string }[]; // <meta>に入っている属性
}>;
code:tampermonkey.js
// ==UserScript==
// @name url-info-proxy
// @namespace https://scrapbox.io
// @version 0.2.1
// @description fetch the title and OGP data from URL
// @author takker
// @match https://scrapbox.io/*
// @connect *
// @grant GM_xmlhttpRequest
// @license MIT
// @unwrap
// @copyright Copyright (c) 2021-2022 takker
// ==/UserScript==
"use strict"
unsafeWindow.fetchURLInfo = (url, {DOM = false} = {}) => new Promise(resolve =>
GM_xmlhttpRequest({
method: "GET",
url,
onload: ({response: arrayBuffer, responseText}) => {
const encoding = getEncoding(responseText);
const html = new TextDecoder(encoding).decode(arrayBuffer);
const dom = new DOMParser().parseFromString(html, 'text/html');
resolve({
encoding,
...(DOM ? {DOM: dom} : {}),
...getPageInfo(dom)});
},
withCredentials: true,
GM_xmlhttpRequestの結果をarrayBufferで受け取る
code:tampermonkey.js
responseType: 'arraybuffer',
})
);
文字コードを判別する
code:tampermonkey.js
function getEncoding(responseText) {
const dom = new DOMParser().parseFromString(responseText, 'text/html');
return dom.querySelector('metacharset')?.getAttribute?.('charset')
?? dom.querySelector('metahttp-equiv="content-type"')
?.content?.match?.(/charset=(^;+)/)?.1
?? 'utf-8';
}
DOMを解析して、meta dataを返す
code:tampermonkey.js
function getPageInfo(dom) {
const metaData = ...dom.head.getElementsByTagName('meta')
.map(meta => {
const names = meta.getAttributeNames();
let result = {};
for (const name of names) {
resultname = meta.getAttribute(name);
}
return result;
});
return {meta: metaData, title: dom.title};
}
#2022-10-01 07:56:18
#2021-02-25 22:33:43