wordpressでajax通信する方法

wordpressに限らず、ajaxはどんなサイトでも使えます。しかし、wordpressではテーマやプラグインなどのファイルをウェブ上から直接操作できるように、ajaxファイルも簡単に弄ることができます。要は、テーマやプラグインなどのディレクトリに専用のディレクトリを作って、そこにファイルを入れていけば良いだけの話だったりします。

wordpressだと標準でjqueryを読込んでいると思いますが、意図的に削除したり、ソースコード内の下の方に移動させている場合は動作しないかも知れません。上手く動かない時はjqueryのバージョンを変えて読み込むか、HEADタグ内など上に移動させて読み込ませてください。以下では、一つ、もしくは二つのajaxファイルを使って非同期通信をする手順を述べたいと思います。

まずは、wordpressでajax通信するためのファイルを用意

この記事では、複数のajaxファイルを並列もしくは直列に読み込むための方法を記述しています。直列のサンプルでは配列内のURLを順不同で読み込みます。並列では二つ以上の要素を必要としますが、配列内の順番通りにURLを読込むサンプルになっています。まずは以下の二つのファイルをプラグインなどのディレクトリに入れて編集します。

ファイル名は「wordpress.php」と「wordpress2.php」としていますが、コード内のURLと一致させれば何でも構いません。

用意するファイルの一つ目の内容

下のコードでは、issetでエラーが出ないようにしていますが、サンプルであるため便宜上そうしているだけです。適切ではありませんので、環境に応じて書き換えて下さい。このファイルの仕組みは、フォームに入力してボタンをクリックしたら非同期通信で読み込んで変数を渡します。

また、ヒアドキュメントにしていますので、EOMとEOMの間で後述するajax用のコードをそのまま<script>タグで挟んで記述すると簡単に出来上がります。

if(!isset($_POST["id_a"],$_POST["pass_a"])){$colon=$_POST["id_a"]=$_POST["pass_a"]="";}else{$colon=":";}
$esc="htmlspecialchars";
echo <<< EOM
<form>
<table style="margin:0 auto;" border=1>
<tr>
<td colspan="4">AJAX</td>
</tr>
<tr>
<td>ID:</td>
<td><input type="text" name="id_a" value="{$esc($_POST["id_a"],ENT_QUOTES)}" /></td>
<td>パスワード</td>
<td><input type="text" name="pass_a" value="{$esc($_POST["pass_a"],ENT_QUOTES)}" /></td>
</tr>
<tr>
<td colspan="4" class="selecon"><span style="font-size:13px;">{$esc($_POST["id_a"],ENT_QUOTES)}{$colon}{$esc($_POST["pass_a"],ENT_QUOTES)}</span></td>
</tr>
<tr>
<td colspan="4" style="text-align:right;"><input type="submit" name="submit" value="送信する" /></td>
</tr>
</table>
</form>
EOM;

用意するファイルの二つ目の内容

こちらは、jqueryコード内で代入した値を非同期通信で受け取るためのファイルです。上記との違いは、フォームで入力した値か、コード内に直接入力した値か、という点です。

// header('Content-Type: application/json; charset=utf-8');
if(!isset($_POST["wordpress_title"],$_POST["wordpress_content"])){$colon=$_POST["wordpress_title"]=$_POST["wordpress_content"]="";}
$esc="htmlspecialchars";
echo <<< EOM
<table style="margin:0 auto;margin-top:10px;" border=1><tr>
<td>title: {$esc($_POST["wordpress_title"],ENT_QUOTES)}</td>
<td>content: {$esc($_POST["wordpress_content"],ENT_QUOTES)}</td>
</tr></table>
EOM;

wordpressからajaxを呼び出すためのコード

以下のコードをwordpressで記事を入力する時の投稿画面に張付けると非同期通信で読み込むようになります。このコードはファイルを読込むためだけのものであるため、変数はダミーにしてあります。従って、変数名は何でも構いません。ただ、wordpressのテンプレートやプラグインから何らかの変数のやりとりをしたい場合は、きちんとした変数を設定します。

また、このコードは上で作ったファイルに後述するajax用のコードを挿入してはじめて動作しますので注意して下さい。このコードだけを投稿本文に貼り付けても動作しません。

<div id="out"></div>
<script>$(function(){var dummy1 = "";$.post('/wp-content/plugins/selfmade/wordpress.php', {dummy:dummy1},function (result){$('#out').html(result);});});</script>

複数のURLを並列と直列でajax通信

並列処理

以下は、thenを使った jQuery1.8以降の書式です。

$('input[name="submit"]').on('click', function(){
var awd = [
{ url: '/wp-content/plugins/selfmade/wordpress.php', params: {id_a : $('input[name="id_a"]').val(), pass_a : $('input[name="pass_a"]').val() } },
{ url: '/wp-content/plugins/selfmade/wordpress2.php', params: { wordpress_title: 'タイトル', wordpress_content: 'これはコンテンツです。' } }
];
var wordpress_ajax = [];
for (var i = 0; i < awd.length; i++) {
wordpress_ajax.push($.ajax({
type: "POST",
url: awd[i].url,
data: awd[i].params,
}));
}
$.when.apply($, wordpress_ajax).then(function () {
var result="";
for (var i = 0; i < arguments.length; i++) {
result = result+arguments[i][0];
}
$('#out').html(result);
},
function () {
alert('エラーが発生しました。');
});
});

直列処理

こちらもjQuery1.8以降のthenを使っています。

$('input[name="submit"]').on('click', function(){
var awd = [
{ url: '/wp-content/plugins/selfmade/wordpress.php', params: {id_a : $('input[name="id_a"]').val(), pass_a : $('input[name="pass_a"]').val() } },
{ url: '/wp-content/plugins/selfmade/wordpress2.php', params: { wordpress_title: 'タイトル', wordpress_content: 'これはコンテンツです。' } }
];
var results = [];
for (var i = 0; i <= awd.length; i++) {
$.ajax({
url: awd[i].url,
data: awd[i].params,
type: 'POST',
}).then(
function (res) {
results.push(res);
$('#out').html(results);
},
function () {
alert('エラーが発生しました。');
});
}
});

一つのURLに対してajax通信

jQuery1.8以降のthenを適用しています。

then

最も一般的な書式です。

$('input[name="submit"]').on('click', function(){
var awd = {
id_a : $('input[name="id_a"]').val(),
pass_a : $('input[name="pass_a"]').val()
};
$.ajax({
type: 'POST',
url: '/wp-content/plugins/selfmade/wordpress.php',
data: awd,
}).then(
function (data) {
$('#out').html(data);
},
function () {
alert('エラーが発生しました。');
});
});

done、fail、always

こちらもjQuery1.8以降のdone、fail、alwaysを用いています。

$('input[name="submit"]').on('click', function(){
var awd = {
id_a : $('input[name="id_a"]').val(),
pass_a : $('input[name="pass_a"]').val()
};
$.ajax({
type: 'POST',
url: '/wp-content/plugins/selfmade/wordpress.php',
data: awd,
}).
done(function(data) {
$('#out').html(data);
}).
fail(function() {
alert('エラーが発生しました。');
}).
always(function() {
// alert('成功、失敗に関係なく通信が終わった時の処理');
});
});

短縮した書式

以下は$.postの短縮形で非同期通信をしています。

$('input[name="submit"]').on('click', function(){
var id_a1 = $('input[name="id_a"]').val();
var pass_a1 = $('input[name="pass_a"]').val();
$.post('/wp-content/plugins/selfmade/wordpress.php',
{id_a:id_a1,pass_a:pass_a1},
function (data){
$('#out').html(data);
});
});

フォーム内データをまとめて取得する方法

こちらは、「$('form').serialize();」でまとめてname属性を取得しています。そのため、nameがキーでvalueが値という形でPOSTやGETの変数を取得できます。ただし、neme属性で取得したいinputやtextareaタグの範囲をまるごと<form>~</form>で囲みます。actionやmethodなどの属性は不要です。広い範囲を指定しても問題ありません。また、ブラウザはformタグがあるとページをリロードしたり変遷したりするため、jqueryでセレクタを指定し、「return false;」でその動作を無効にします。serializeは簡単にいうとデータをそのままの形で送受信させるためのもので、この場合だと配列を配列として処理させるためのものですかね。

$('input[name="submit"]').on('click', function(){
var awd = $('form').serialize();
$.post('/wp-content/plugins/selfmade/wordpress.php',
awd,
function (data){
$('#out').html(data);
});
});
$('form').on('submit',function(){
return false;
});

successを用いた古い書式

こちらはjQuery1.0時代の古い書式です。jqueryのバージョンによっては動かないかも知れません。success、error、completeを使って処理しています。

// jQuery1.0
$('input[name="submit"]').on('click', function(){
var awd = {
id_a : $('input[name="id_a"]').val(),
pass_a : $('input[name="pass_a"]').val()
};
$.ajax({
type: 'POST',
url: '/wp-content/plugins/selfmade/wordpress.php',
data: awd,
success: function(data) {
$('#out').html(data);
},
error:function() {
alert('エラーが発生しました。');
},
complete:function() {
// alert('成功、失敗に関係なく通信が終わった時の処理');
},
});
});

その他のオプション

typeやurl、dataと共に以下のオプションなども指定できますので、ご利用環境に合わせて使い分けて下さい。

cache: false,
dataType: "json",
contentType: 'application/json',
traditional: true,

直接アクセスさせないための対策

以下のコードをajaxファイルの先頭に記述すると、そのファイルに対する直接のアクセスを拒否することができます。つまり、上に述べたwordpressの記事内に設定したコードのあるページ以外からは、ajaxファイルへアクセスできないようにするためのものです。適切に処理していればアクセスされても特に問題ないので構わないのですが、検索エンジンのロボットによっては、このページにアクセスしてきます。基本的に直接アクセスされてもコンテンツがロクに表示されないため、404か403エラーを返しておいたほうが無難です。ただ、ブラウザによってはリファラーを切っている場合があり、そういったケースではユーザのブラウザで非同期通信による読み込みはされません。

$referer="";
if(!empty($_SERVER["HTTP_REFERER"])){$referer = $_SERVER["HTTP_REFERER"];}
$url = (empty($_SERVER["HTTPS"]) ? "http://" : "https://") . $_SERVER["HTTP_HOST"].'/wordpressの記事までのパス/';
if(!strstr($referer,$url)){
header(' ', true, 403);
echo '<p>正しい画面からお入りください</p>';
exit;
}

まとめ

非同期通信とは、つまるところajaxのことです。postやgetなどの指定もできることからイメージを掴みにくくなっていますが、分かりやすくいうと現在見ているページに対してバッググラウンドでファイルをダウンロードしているだけです。ただ、こういった技術を使うと、レンダリングを妨げるリソースを除外することができます。リソースとは、javascriptやcssなどのことです。巨大なjavascriptコードなんかもこういった形でバックグラウンドでダウンロードさせるとストレスなく画面にコンテンツを出力することが出来たりします。しかし、一番のメリットはページを変遷しないでコンテンツを切り替えられる点ですかね。

尚、ajaxをあまり弄ったことがない場合、変数のやりとりが上手くいかないかも知れません。ですが、弄っているとだんだん分かってきますので、めげずに頑張って下さい。