JavaScriptでサーバに設定されている日時を取得する方法を忘れないようにメモっておきます。PHPとかなら簡単なはずなんですけどね。結構、手こずったので色々備忘録的に書いておこうと思います。同じような課題に出くわした方の参考になれば幸いです。
ただ、JavaScriptはあまり得意ではないので、勉強しながらやってます。以下、あくまでご参考程度に。より良い方法があったら、ぜひご教授いただきたいです。
JavaScript関連の他の記事
よかったらこちらも合わせてどうぞ
やりたいこと
まずは、やりたいことの説明から。やりたかったのは以下のようなことです:
- フォームで年月日の入力を3つのドロップダウンに分けて設置する
- その際、「年」のオプションを現在の年をベースに自動で書き出したい
- PHPなどのサーバサイド言語を使えない環境で実装する
たとえば、2017年には2015年から2019年を選択肢として表示していたものを、2018年になったらコードの更新なしに2016年から2020年を表示するようにしたいわけです。
年に1回の更新なんで、そんなに手間ではないんですけど、あまり頻繁に起こらない更新って、うっかり忘れてしまうことが多いし、覚えておかなければならない負担というのもあるので、やっぱり自動化したいです。
PHPで書けたら楽なんですけどねぇ。CRMツールとの連携とかで、そういったサーバサイド言語が使えないこともあるので、仕方なくJavaScriptでできる方法にしました。
ソースコード
以下、最終的にたどり着いたコードです。ここではテストのために日時の取得までで、フォームのドロップダウンの構築まではしていません。
Ajaxを使って、サーバから返されるレスポンスヘッダーの日時を取得しています。取得した日時を、一番上の<span id="server">
に挿入しています。ちなみに、古いブラウザもサポートできるようにjQuery 1.11.1を使ってます。本来はjQuery使わなくてもいいんですけどね。
修正・追記(2017/11/18):
ページにアクセスしたことがありブラウザのキャッシュが残っている場合、キャッシュのHEAD情報を取得してしまうので$.ajax
のオプションにcache : false
を追加しました。
<p><strong>Server Time:</strong> <span id="server"></span></p>
<p><strong>Client Time:</strong> <span id="client"></span></p>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
function getServerDate(callback){
$.ajax({
type : 'HEAD',
url : window.location.href,
cache : false
}).done(function(data, textStatus, xhr) {
try {
var result = new Date(xhr.getResponseHeader("Date"));
} catch(e) {
var result = new Date();
}
callback(result);
}).fail(function() {
var result = new Date();
callback(result);
});
}
function makeHTML(result){
$("#server").html(result);
}
getServerDate(makeHTML);
var clientDate = new Date();
$("#client").html(clientDate);
</script>
コードの説明
$.ajax({
type : 'HEAD',
url : window.location.href,
cache : false
まず、$.ajax()
を使ってページ自体をwindow.location.href
でリクエストして、HEAD情報を読み込みます。以前ページにアクセスしたことがありキャッシュにページが残っている場合、過去のHEAD情報を読み込んでしまうのでcache : fase
を指定します。(修正・追記: 2017/11/18)
$.ajax({
// Ajaxコール
}).done() {
// Ajaxコールが成功した場合の処理
}).fail() {
// Ajaxコール失敗した場合の処理
};
HEAD情報が読み込みできたら、getResponseHeader("Date")
で日時を取得します。Ajaxの読み込みが失敗した時のことを考えてdone()
とfail()
を使ってその処理を書いています。done()
はAjaxコールが完了した際に実行するコード。fail()
は失敗した時ですね。
}).done(function(data, textStatus, xhr) {
try {
var result = new Date(xhr.getResponseHeader("Date"));
} catch(e) {
var result = new Date();
}
getResponseHeader
でDateの取得が失敗した時のために、try ... catch
でエラー処理をしています。Android 2.3系でDateの取得ができないことがあるらしい です。エラーがあった場合はクライアント側の日時を取得するようにしています。
function getServerDate(callback){
callback(result);
}
function makeHTML(result){
$("#server").html(result);
}
getServerDate(makeHTML);
スクリプトの全体の構造はこんな感じなんですが、getServerDate(makeHTML)
でmakeHTML
をコールバックとして読み込んでいて、そこでHTMLの書き出し処理をしています。
Advertisement
その他の方法 x 2
上述したやり方にたどり着くまでにいろいろ試して、他にも日時の取得ができる方法があったので、一応晒しておきます。ちなみに、以下の2つの方法だとAjaxコールを行う際に、async: false
オプションで同期的にAjax処理を行うようにしていて、処理に問題があった場合にUIがロックされてしまうとのことで、オススメできません。
jQuery.extend()を使う方法
jQuery.extend()
を使うことで、getServerDate
からの返り値を関数の外で読めるようになってるようなんですよね。仕組みをよく理解できてないんですけど。。。あと、ここではdone()
とfail()
ではなくてcomplete
とerror
を使って、Ajaxのエラー処理をしています。ここでもgetResponseHeader("Date")
のエラー処理も別途するべきなんでしょうけど、書いてません。
jQuery.extend({
getServerDate: function(url){
var result = null;
$.ajax({
type : 'HEAD',
url : url,
async: false,
complete : function(xhr){
result = xhr.getResponseHeader("Date");
},
error : function(){
result = new Date();
}
});
return result;
}
});
var strURL = window.location.href;
var serverDate = new Date($.getServerDate(strURL));
var clientDate = new Date();
$("#server").html(serverDate);
$("#client").html(clientDate);
jQuery.extend()を使わない方法
以下のコードではjQuery.extend()
を使わずに返り値を関数の外で取得できました。こちらの方法も、async: false
じゃないと動かないので通信に問題があった場合のことを考えるとオススメできません。残念ながら。。。
function getServerDate(){
var strURL = window.location.href;
var result = $.ajax({
type : 'HEAD',
url : strURL,
async: false
}).getResponseHeader("Date");
return result;
}
var serverDate = new Date(getServerDate());
if(serverDate == null){
serverDate = new Date();
}
var clientDate = new Date();
$("#server").html(serverDate);
$("#client").html(clientDate);
まとめ
以上、JavaScriptだけでサーバの日時を取得する方法でした。
サーバの日時取得するだけなのに、かなり面倒ですよねぇ。まぁ、最近では何らかのサーバサイド言語を使用することも多いと思うので、あまり必要性はないのかもしれないですけど。参考になれば幸いです。
では、Happy coding!
JavaScript関連の他の記事
よかったらこちらも合わせてどうぞ
参考にさせてもらったサイト
- jQueryのajax()を利用すると返り値をとりたいときのやり方 – Qiita
- JavaScript でサーバのレスポンスヘッダの時刻を取得して使いたい – Qiita
- How do I return the response from an asynchronous call? – Stack Overflow
2017年1月20日に公開され、2017年12月25日に更新された記事です。
About the author
「明日のウェブ制作に役立つアイディア」をテーマにこのブログを書いています。アメリカの大学を卒業後、ボストン近郊のウェブ制作会社に勤務。帰国後、東京のウェブ制作会社に勤務した後、ウェブ担当者として日英バイリンガルのサイト運営に携わる。詳しくはこちら。
ウェブ制作・ディレクション、ビデオを含むコンテンツ制作のお手伝い、執筆・翻訳のご依頼など、お気軽にご相談ください。いずれも日本語と英語で対応可能です。まずは、Mastodon @rriver@vivaldi.net 、Twitter @rriver 、またはFacebook までご連絡ください。
[…] JavaScriptだけでサーバーの日時を取得する方法のメモ – Rriver […]