Vue.jsを使ってConnpassのAPIを利用したアプリを作ろうと思った。
#クロスオリジン制約
フロントから(jQuery)直接APIをたたくことは出来ない(クロスオリジン制約)。
しかしPHPなら可能。
その場合 Guzzle というものを使う。下のような順番のコードを書く。
- phpでGuzzle使ってAPIをたたく
- JSONでJSファイルにデータを返す
- Vue.jsでフロントにデータを表示させる
#Guzzleをインストール
$ composer init //composer.jsonつくる
$ composer require guzzlehttp/guzzle
$ composer require illuminate/http
#先にhttpライブラリを使ってJSONを返せるように練習
httpライブラリのJsonResponseを使う。
<?php
require __DIR__ . "/../../vendor/autoload.php";
use Illuminate\Http\JsonResponse;
$data = [
"message" => "Hello World",
"hogehoge" => "hogehoge",
"event" => [
"php勉強会",
"laravel勉強会",
"jQuery勉強会",
]
];
$response = JsonResponse::create($data,200);
$response->send();
##タイムゾーンのエラーがでるとき
error_reporting(0);
を最初に入れる。
###原因
php iniファイルでタイムゾーンがない状態らしい。
上記コードでタイムゾーンエラーはなくなる。
でも根本的な解決ではないからできればphp iniファイルをAsia/Tokyoに直す方が良い。
#guzzleライブラリを使って外部APIをたたく
いよいよAPIをたたく。
<?php
require __DIR__ . "/../../vendor/autoload.php";
use Illuminate\Http\JsonResponse;
use GuzzleHttp\Client;
$url = "http://connpass.com/api/v1/event/";
$client = new Client();
$res = $client->get($url, [
"query" => [
"start" => $start
]
]);
$data = json_decode($res->getBody(),true);
$response = JsonResponse::create($data,200);
$response->send();
$data = json_decode($res->getBody(),true);
の true/false は array/object で返ってくる、ということ。
ちなみにデフォルトだとfalseになるので object で返ってくるので注意。
キャストを使った場合はその箇所でしか配列にならない。
#問題発生:phpファイルの生コードがそのまんま返ってきてしまう
$(function(){
var app = new Vue ({
el: "#app",
data: {
posts: []
},
created: function(){
var xhr = $.get("./api/event.php", {start: 0});
xhr.success(function(data){
app.posts = data.events;
});
xhr.error(function(){
alert("通信に失敗しました"); //失敗時の処理
});
}
});
});
これで本来ならAPIのデータが取れているはず。
なのにphpの生コードが返されるだけだった・・・。
##原因:GuzzleでAPIをたたくならphpのサーバーを使わなければいけない。
GulpのWebサーバーを使っていたことが原因。
phpのサーバーの上にGulpのプロキシサーバーをつける感じらしい。
(あまり良くわかってない)
var gulp = require("gulp");
var browser = require("browser-sync");
var php = require("gulp-connect-php");
gulp.task("server", function(){
var config = {
proxy: "***.*.*.*:8000",
open: "external"
//notify: false
};
var server = {
base: "./public" /*phpのサーバー*/
};
php.server(server,() => {
browser(config)
});
gulp.watch(`./public/**/*`, () => {
setTimeout(function(){
browser.reload();
},500);
});
gulp.watch([
"./frontend/assets/sass/**/*.scss"
], function(){
setTimeout(function(){
browser.reload();
}, 500);
})
});```