WEBページを作って運用する時に、CMSのツールを使っていると、サイト内部のリンク切れは、自動で処理されて表示されないようにしてくれる機能があるけど、
外部サイトのURLをリンクした時に、そのリンク先がなくなっている場合などは、リンククリックしたユーザーが残念な思いをするだけです。
昔からリンク切れ検知ツールっていくつもあるけど、リアルタイムクローリングしているようなサイトじゃないと最近はあまり見かけなくなりました。
とりあえず、簡単なソースコードでツール化してみたので、使いたい人はお試しあれ。
機能概要
外部リンク表示
サイト内リンクは、そのままで、外部リンクは、外部リンクアイコンを表示。
表示しているURLとリンク先のhostnameを判定してます。
リンク切れ表示
レスポンスステータスが「200」番以外は、リンク切れ判定にしてます。
ローカルPHPで処理してます。
javascriptでは、クロスドメイン制約がありどうしても突破できないので、ローカルphpを一つ設置する方式にしてます。
ソースコード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8"/>
<title>check-broken-links</title>
<script type="text/javascript" src="checkBrokenLink.js"></script>
</head>
<body>
<ol>
<li><a href="index.html">index.html</a></li>
<li><a href="http://hoge.yahoo.co">http://hoge.yahoo.co.jp</a></li>
<li><a href="https://github.com/">https://github.com/</a></li>
<li><a href="hoge.html">nothing link</a></li>
<li><a href="img.html"><img src="img/sample.jpg"></a></li>
</ol>
</body>
</html>
/**
* check broken link
* 2018.2.16 Koji.Yugeta
* [Summery]
*
* [Usage]
*
*/
;(function(){
var $$ = function(){
window.addEventListener("load",$$.prototype.start);
};
$$.prototype.start = function(){
$$.prototype.setStyle();
var links = document.links;
for(var i=0; i<links.length; i++){
if(location.hostname !== links[i].hostname){
links[i].className += " external-link";
links[i].target = "_blank";
var url = "//"+location.hostname+location.pathname+"checkBrokenLink.php?url="+links[i].href;
new $$ajax({
url:url,
data:{
elm:links[i]
},
method:"get",
onSuccess:function(res){
if(res.responseText === "200"){console.log("-");
// console.log(res.responseText);
}
else if(res.responseText === ""){console.log("+");
this.data.elm.className += " broken-link";
}
},
onError:function(event){
this.data.elm.className += " broken-link";
}
});
}
else{
var url = links[i].href;
new $$ajax({
url:url,
data:{
elm:links[i]
},
method:"get",
onError:function(event){
this.data.elm.className += " broken-link";
}
});
}
}
// var sc = document.getElementById("test");
// console.log(sc);
};
$$.prototype.setStyle = function(){
var css = "";
css += ".external-link{"+"\n";
css += " display:inline-block;";
css += "}"+"\n";
css += ".external-link:after{";
css += " content:'';";
css += " display:inline-block;";
css += " height:16px;";
css += " width :16px;";
css += " vertical-align :middle;";
css += " padding-left:8px;";
css += " background-image: url('img/external-link.svg');";
css += " background-size: 100% 100%;";
css += "}";
css += ".broken-link{"+"\n";
css += " display:inline-block;";
css += "}"+"\n";
css += ".broken-link:after{";
css += " content:'';";
css += " display:inline-block;";
css += " min-height:14px;";
css += " max-height:24px;";
css += " height:100%;";
css += " width :16px;";
css += " background-image: url('img/caution.svg');";
css += " background-size: 100% 100%;";
css += " vertical-align :middle;";
css += " padding-left:8px;";
css += "}";
var style = document.createElement("style");
style.innerHTML = css;
document.getElementsByTagName("head")[0].appendChild(style);
};
var $$ajax = function(options){
if(!options){return}
var ajax = new $$ajax;
var httpoj = $$ajax.prototype.createHttpRequest();
if(!httpoj){return;}
// open メソッド;
var option = ajax.setOption(options);
// 実行
httpoj.open( option.method , option.url , option.async );
// type
httpoj.setRequestHeader('Content-Type', option.type);
// onload-check
httpoj.onreadystatechange = function(){
//readyState値は4で受信完了 (2は受信途中)
if (this.readyState == "4"){
// 受信成功
if(this.status == "200"){
option.onSuccess(this);
}
// ページエラー
else if(this.status == "404"){
option.onError(this);
}
// それ以外
else{
option.onStatus(this);
}
}
};
//query整形
var data = ajax.setQuery(option);
//send メソッド
if(data.length){
httpoj.send(data.join("&"));
}
else{
httpoj.send();
}
};
$$ajax.prototype.dataOption = {
url:"",
query:{}, // same-key Nothing
querys:[], // same-key OK
data:{}, // ETC-data event受渡用
async:"true", // [trye:非同期 false:同期]
method:"POST", // [POST / GET]
type:"application/x-www-form-urlencoded", // [text/javascript]...
onSuccess:function(res){},
onStatus:function(res){},
onError:function(res){}
};
$$ajax.prototype.option = {};
$$ajax.prototype.createHttpRequest = function(){
//Win ie用
if(window.ActiveXObject){
//MSXML2以降用;
try{return new ActiveXObject("Msxml2.XMLHTTP")}
catch(e){
//旧MSXML用;
try{return new ActiveXObject("Microsoft.XMLHTTP")}
catch(e2){return null}
}
}
//Win ie以外のXMLHttpRequestオブジェクト実装ブラウザ用;
else if(window.XMLHttpRequest){return new XMLHttpRequest()}
else{return null}
};
$$ajax.prototype.setOption = function(options){
var option = {};
for(var i in this.dataOption){
if(typeof options[i] != "undefined"){
option[i] = options[i];
}
else{
option[i] = this.dataOption[i];
}
}
return option;
};
$$ajax.prototype.setQuery = function(option){
var data = [];
if(typeof option.query != "undefined"){
for(var i in option.query){
data.push(i+"="+encodeURIComponent(option.query[i]));
}
}
if(typeof option.querys != "undefined"){
for(var i=0;i<option.querys.length;i++){
if(typeof option.querys[i] == "Array"){
data.push(option.querys[i][0]+"="+encodeURIComponent(option.querys[i][1]));
}
else{
var sp = option.querys[i].split("=");
data.push(sp[0]+"="+encodeURIComponent(sp[1]));
}
}
}
return data;
};
new $$;
})();
<?php
if(isset($_REQUEST["url"])){
$res = get_headers($_REQUEST["url"],1);
echo trim(str_replace("OK","",$res["Status"]));
}
その他画像など
※画像は、FREEの物を適当にDLしてお使いください。
icon finder
画面イメージ
今回は、少し手抜きをして、デモページを作っていません。
画像で勘弁ください。
リンク切れと、外部リンクの右側に、アイコンが表示されているのが分かりますか?
最近こうした気の利いたUIのサイトもたま〜に見かけるようになりましたが、こうした小さなおもてなしができるWEBサイトが、知らない間に使いやすいサイトという事なんでしょうね。
0 件のコメント:
コメントを投稿