htmlファイルのリンクをチェックするブックマークレットを作った

フロントエンドコーディングの品質管理において何か良いツールはないかと探していたところ、知人に下記を紹介してもらった。

alt属性を確認するブックマークレット。

ブックマークレットということでブラウザさえ対応していればWindows,Macを選ばずサクサクと実行することができる。
このブックマークレットにインスパイアされ、ページ内のリンクをチェックするブックマークレットを自作してみた。

javascript:(function(d) {
    function l() {
        (function($) {
            var rid = 'ALL_link_check';
            if (document.getElementById(rid))
                return;
            function e(t) {
                return document.getElementsByTagName(t);
            }
            function a(o, a) {
                return o.getAttribute(a);
            }
            anchors = document.getElementsByTagName('a');
            if (anchors.length <= 0)
                return;
            var r = document.createElement('div');
            var rcss = 'padding:5px;position:absolute;top:0;left:0;background:#fff;border:solid #ccc 1px;z-index:2999;';
            var tblcss = ' style=\'border-collapse:collapse;background:#fff;\'';
            var tdlcss = ' style=\'padding:4px;border-bottom:solid #ffffff 2px;text-align:right;\'';
            var tdrcss = ' style=\'padding:4px;border-bottom:solid #ffffff 2px;text-align:left;\'';
            r.id = rid;
            r.style.cssText = rcss;
            var h = '';
            h += 'Checking link existence....';
            for (var j = 0; j < anchors.length; j++) {
                h += (j % 2 == 0) ? '' : '';
                h += '' + anchors[j].innerHTML + '' + a(anchors[j], 'href') + '';
            }
            h += '';
            e('body')[0].appendChild(r);
            r.innerHTML = h;
            r.onclick = function() {
                this.parentNode.removeChild(this);
            };
            window.scrollTo(0, 0);
            function checkurl(id, geturl, maxcnt) {
                $.post(geturl, {value: 1}, function(data) {
                }).fail(function(error) {
                    if (error.status == 404) {
                        $('#existcheck' + id).css('background-color', '#ff0000');
                    } else {
                        $('#existcheck' + id).css('background-color', '#0000ff');
                    }
                }).always(function() {
                    if (geturl == '#') {
                        $('#existcheck' + id).css('background-color', '#ff0000');
                    }
                    if (!geturl) {
                        $('#existcheck' + id).css('background-color', '#ff0000');
                    }
                    if (id == maxcnt - 1) {
                        $('#checkinglink').html('Done!!');
                    }
                });
            }
            var maxcnt = anchors.length;
            for (var j = 0; j < maxcnt; j++) {
                var geturl = a(anchors[j], 'href');
                checkurl(j, geturl, maxcnt);
            }
        })(jQuery)
    }
    if (typeof jQuery == 'undefined') {
        var j = d.createElement('script');
        j.type = 'text/javascript';
        j.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js';
        d.body.appendChild(j);
        j.onload = l
    } else {
        l()
    }
})(document);

本来であれば直接ブックマークに追加できるよう掲載したかったが、なぜかうまくいかなかったので、上記コードをコピーし、このサイト でブックマークレット形式に変換して利用してほしい。

ブックマークバーに保存したあとは、対象のウェブサイトで実行すると、下記のように全てのリンクの一覧が表示される。
その後、ajaxで各リンクの存在チェックを行い、リンク切れのところは赤に、外部リンクは青にハイライトされる仕様だ。
Chromeの最新版で動作確認済み。
ブックマークレット

フロントエンドコーディング担当者には品質チェックの一環として、担当ページの提出前にこれを実行してもらおうと思う。

PHPのcurlでeuc-jpのページを取得したときに文字化けするのを防ぐ

俺日記のしんじです。一人称は僕です。

下記のようなcurlの関数を用意し、euc-jpのページを取得し、シェル内でで取得したページを確認すると文字化けしていることに気づいた。

function curl_get_contents($url, $timeout = 60) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

上記コードを下記のように変更することで文字化けを防ぐことができる。

function curl_get_contents($url, $timeout = 60) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    $result = curl_exec_utf8($ch);
    curl_close($ch);
    return $result;
}

/** The same as curl_exec except tries its best to convert the output to utf8 * */
function curl_exec_utf8($ch) {
    $data = curl_exec($ch);
    if (!is_string($data))
        return $data;

    unset($charset);
    $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);

    /* 1: HTTP Content-Type: header */
    preg_match('@([\w/+]+)(;\s*charset=(\S+))[email protected]', $content_type, $matches);
    if (isset($matches[3]))
        $charset = $matches[3];

    /* 2:  element in the page */
    if (!isset($charset)) {
        preg_match('@ element in the page */
    if (!isset($charset)) {
        preg_match('@<\?xml.+encoding="([^\s"]+)@si', $data, $matches);
        if (isset($matches[1]))
            $charset = $matches[1];
    }

    /* 4: PHP's heuristic detection */
    if (!isset($charset)) {
        $encoding = mb_detect_encoding($data);
        if ($encoding)
            $charset = $encoding;
    }

    /* 5: Default for HTML */
    if (!isset($charset)) {
        if (strstr($content_type, "text/html") === 0)
            $charset = "ISO 8859-1";
    }

    /* Convert it if it is anything but UTF-8 */
    /* You can change "UTF-8"  to "UTF-8//IGNORE" to 
      ignore conversion errors and still output something reasonable */
    if (isset($charset) && strtoupper($charset) != "UTF-8")
        $data = iconv($charset, 'UTF-8', $data);

    return $data;
}

参考:http://stackoverflow.com/questions/2510868/php-convert-curl-exec-output-to-utf8

以上。