JavaScriptだけでサーバーの日時を取得する方法のメモ

Advertisement

JavaScriptでサーバに設定されている日時を取得する方法を忘れないようにメモっておきます。PHPとかなら簡単なはずなんですけどね。結構、手こずったので色々備忘録的に書いておこうと思います。同じような課題に出くわした方の参考になれば幸いです。

ただ、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()ではなくてcompleteerrorを使って、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!

参考にさせてもらったサイト

About the author

Rriverのステッカーが貼られたMacBookの向こうにいる自分のMemojiの似顔絵

「明日のウェブ制作に役立つアイディア」をテーマにこのブログを書いています。アメリカの大学を卒業後、ボストン近郊のウェブ制作会社に勤務。帰国後、東京のウェブ制作会社に勤務した後、ウェブ担当者として日英バイリンガルのサイト運営に携わる。詳しくはこちら

ウェブ制作・ディレクション、ビデオを含むコンテンツ制作のお手伝い、執筆・翻訳のご依頼など、お気軽にご相談ください。いずれも日本語と英語で対応可能です。まずは、Mastodon @rriver@vivaldi.net Twitter @rriver 、またはFacebook までご連絡ください。

“JavaScriptだけでサーバーの日時を取得する方法のメモ” への1件のコメント

  1. […] JavaScriptだけでサーバーの日時を取得する方法のメモ – Rriver […]