Symfoware

Symfowareについての考察blog

axios クロスドメインへのpostリクエストでRequest header field Content-Type is not allowed

axiosを使用して、クロスドメインにpostするとこんなエラーが。

XMLHttpRequest cannot load http://192.168.1.103:8000/api.php.
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.


こちらが参考になりました。
Axios CORS issue with Github oauth Not getting access token
OAuth web flow endpoints don't support CORS

「OPTIONS」メソッドのリクエストが来た時、許可する処理を
ヘッダーに書き込んで応答します。

Detecting request type in PHP (GET, POST, PUT or DELETE)


phpでのサンプルはこんな感じになりました。


  1. <?php
  2. if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  3.     header('Access-Control-Allow-Origin: *');
  4.     header('Access-Control-Allow-Headers: Content-Type');
  5.     header('Access-Control-Allow-Methods: GET, POST');
  6.     exit();
  7. }
  8. header('Access-Control-Allow-Origin: *');
  9. header('Content-type: application/json; charset=UTF-8');
  10. $result = [
  11.     ['id' => 1, 'name' => '一番'],
  12.     ['id' => 2, 'name' => '二番'],
  13.     ['id' => 3, 'name' => '三番'],
  14.     ['id' => 4, 'name' => '四番'],
  15.     ['id' => 5, 'name' => '五番']
  16. ];
  17. echo json_encode($result);





これでpost通信できるようになりました。

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/07/30(日) 17:09:20|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Phonon Framework パネルが閉じた時のイベントを取得する

やりたいことは、フローティングのボタンを表示。

762_01.png

ボタンを押した時にパネルを表示。
フローティングボタンは非表示に。

762_02.png


パネルを非表示にした時、フローティングボタンを再表示。
パネルを閉じた時のイベントを取得したい。


onTransitionEnd



パネルが表示された時、非表示になった時にonTransitionEndイベントが発生します。
また、パネルが表示されているときは「active」というクラスがdivに対して設定されています。

これを利用して、こんな感じのソースにしてみました。
※前回のソースの続きです。
Phonon + Riot 画面遷移サンプル


・www/tags/home.tag


  1. <home>
  2.     <header class="header-bar">
  3.         <div class="center">
  4.             <h1 class="title">Phonon+Riot</h1>
  5.         </div>
  6.     </header>
  7.     <div class="content">
  8.         <ul class="list">
  9.             <li class="divider">一覧表示</li>
  10.             <li each={ items }>
  11.                 <a class="padded-list" href="#!pagetwo/{id}">{name}</a>
  12.             </li>
  13.         </ul>
  14.         <div id="addpanel" class="panel">
  15.                 <header class="header-bar">
  16.                     <a class="btn icon icon-close pull-right" href="#"></a>
  17.                     <h1 class="title">Panel</h1>
  18.                 </header>
  19.                 <div class="content">
  20.                     <p class="padded-full">The contents of my panel go here.</p>
  21.                 </div>
  22.         </div>
  23.         <button id="add" class="floating-action icon icon-add active primary bottom right" show={ floatingShow }></button>
  24.     </div>
  25.     <script>
  26.         var self = this
  27.         self.floatingShow = true
  28.         self.items = []
  29.         this.on('create', function() {
  30.             var floating = document.getElementById('add')
  31.             var panel = document.getElementById('addpanel')
  32.             floating.on('tap', function() {
  33.                 self.update({floatingShow : false})
  34.                 phonon.panel('#addpanel').open()
  35.             })
  36.             // transitionendイベントを監視
  37.             // activeクラスが設定されていなければ閉じた後
  38.             document.getElementById('addpanel').on('transitionend', function(event) {
  39.                 if (!event.target.classList.contains('active')) {
  40.                     self.update({floatingShow : true})
  41.                 }
  42.             })
  43.         })
  44.         this.on('ready', function() {
  45.             axios.get('http://192.168.1.4:8000/cgi-bin/sample.py', {params:{mode:'list'}})
  46.                 .then(function (response) {
  47.                     self.update({items : response.data})
  48.                 }).catch(function (error) {
  49.                     console.log(error)
  50.                 });
  51.             
  52.         })
  53.     </script>
  54. </home>




これで狙い通りの動作になりました。
本当はon('close')が使えればよいのですが、イベント発火しないようです。


テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/07/30(日) 15:45:22|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Phonon + Riot 画面遷移サンプル

・Cordova
・Phonon Framework
・Riot
・axios

この組み合わせでのアプリケーション開発を試しています。
Phonon + Riot + axiosでajax通信のサンプルプログラム

前回、ajax通信でデータを取得。
取得した内容を一覧で表示してみました。

今回は、一覧の項目をタップすると詳細ページを表示するようにしてみます。


サンプル



2ページめの画面は「www/tags/pagetwo.tag」に作成します。
index.htmlとapp.jsに追加したページを読み込む処理を追加。


・www/index.html


  1. <!DOCTYPE html>
  2. <html>
  3.     <head>
  4.         <meta charset="utf-8" />
  5.         <meta name="format-detection" content="telephone=no" />
  6.         <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height" />
  7.         <link rel="stylesheet" href="css/phonon.css" />
  8.         <title>App</title>
  9.     </head>
  10.     <body>
  11.         
  12.         <!-- Panel tags go here -->
  13.         <!-- Side Panel tags go here -->
  14.         <!-- Notification tags go here -->
  15.         <!-- Dialog tags go here -->
  16.         <home data-page="true"></home>
  17.         <pagetwo data-page="true"></pagetwo>
  18.         <!-- page tags -->
  19.         <script src="tags/home.tag" type="riot/tag"></script>
  20.         <script src="tags/pagetwo.tag" type="riot/tag"></script>
  21.         <!-- scripts -->
  22.         <script src="js/riot+compiler.min.js"></script>
  23.         <script src="js/axios.min.js"></script>
  24.         <script src="js/phonon.js"></script>
  25.         <!-- our app config -->
  26.         <script src="js/app.js"></script>
  27.     </body>
  28. </html>





・www/js/app.js


  1. phonon.options({
  2.     navigator: {
  3.         defaultPage: 'home',
  4.         animatePages: true,
  5.         enableBrowserBackButton: true,
  6.     },
  7.     i18n: null
  8. });
  9. var app = phonon.navigator();
  10. app.on({page: 'home', preventClose: false, content: null});
  11. app.on({page: 'pagetwo', preventClose: true, content: null, readyDelay: 1});
  12. app.start();





home.tagには、遷移先のページリンクを指定。
「#!pagetwo/{id}」とし、idを次のページの引数とします。


・www/tags/home.tag


  1. <home>
  2.     <header class="header-bar">
  3.         <div class="center">
  4.             <h1 class="title">Phonon+Riot</h1>
  5.         </div>
  6.     </header>
  7.     <div class="content">
  8.         <ul class="list">
  9.             <li class="divider">一覧表示</li>
  10.             <li each={ items }>
  11.                 <a class="padded-list" href="#!pagetwo/{id}">{name}</a>
  12.             </li>
  13.         </ul>
  14.     </div>
  15.     <script>
  16.         var self = this
  17.         self.items = []
  18.         this.on('ready', function() {
  19.             axios.get('http://192.168.1.4:8000/cgi-bin/sample.py', {params:{mode:'list'}})
  20.                 .then(function (response) {
  21.                     self.update({items : response.data})
  22.                 }).catch(function (error) {
  23.                     console.log(error)
  24.                 });
  25.             
  26.         })
  27.     </script>
  28. </home>





追加したページでは、idを取得してデータを検索。
結果を表示します。

・www/tags/pagetwo.tag


  1. <pagetwo class="app-page">
  2.     <header class="header-bar">
  3.         <div class="left">
  4.             <button class="btn pull-left icon icon-arrow-back" data-navigation="$previous-page"></button>
  5.             <h1 class="title">Page Two</h1>
  6.         </div>
  7.     </header>
  8.     <div class="content">
  9.         <div class="padded-full">
  10.             <h2>{info.name}</h2>
  11.             <p>{info.comment}</p>
  12.         </div>
  13.     </div>
  14.     <script>
  15.         var self = this
  16.         this.info = {}
  17.         this.on('close', function(self) {
  18.             self.close()
  19.         })
  20.         this.on('hashchanged', function(id) {
  21.             self.name = id
  22.             axios.get('http://192.168.1.4:8000/cgi-bin/sample.py', {params:{mode:'detail', id:id}})
  23.                 .then(function (response) {
  24.                     self.update({info : response.data})
  25.                 }).catch(function (error) {
  26.                     console.log(error)
  27.                 });
  28.         })
  29.     </script>
  30. </pagetwo>






サーバー側として動作するcgiはこんな感じ。

・cgi-bin/sample.py


  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. import json
  4. import cgi
  5. import cgitb
  6. cgitb.enable(display=0, logdir='./')
  7. print('Access-Control-Allow-Origin: *')
  8. print('Content-type: text/javascript; charset=UTF-8\r\n')
  9. form = cgi.FieldStorage()
  10. mode = form['mode'].value
  11. if mode == 'list':
  12.     result = [
  13.         {"id" : 1, "name" : "一番"},
  14.         {"id" : 2, "name" : "二番"},
  15.         {"id" : 3, "name" : "三番"},
  16.         {"id" : 4, "name" : "四番"},
  17.         {"id" : 5, "name" : "五番"}
  18.     ]
  19. elif mode == 'detail':
  20.     id = form['id'].value
  21.     result = {
  22.         'id' : id,
  23.         'name' : id + '番のデータ',
  24.         'comment' : id + '番のデータは有効です'
  25.     }
  26. print(json.dumps(result))





簡単なサンプルですが、起動時に一覧を表示。

761_01.png


名称をタップすると、2ページめを表示してくれました。

761_02.png


テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/07/30(日) 14:28:40|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Cordovaのデバッグ console.log出力を表示する

Cordovaでconsole.log出力した文字列を確認する方法がわからなかったのでメモ。

こちらがとても参考になりました。
Cordovaとandroidでデバッグするときの備忘録


$ adb logcat chromium:V *:S




こんな感じで出力の内容が表示されます。

760_01.png

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/07/29(土) 18:09:09|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Phonon + Riot + axiosでajax通信のサンプルプログラム

・Cordova
・Phonon Framework
・Riot

この組み合わせでのアプリケーション開発を試しています。
Cordova + Phonon + Riotでサンプルアプリケーションを実行する


今回は、ajax通信でサーバーからデータを取得。
結果をリスト表示してみようと思います。



axios



Riotでajax通信は以前試してみました。
Riot ajaxで取得したjsonデータをテーブルに表示する(axios使用)

今回もaxiosを使用してみようと思います。


使用しているフレームワークへのリンクはこちら。
Phonon Framework
Riot
axios

今回使用したバージョンは以下のとおりです。

Phonon Framework:v1.4.5
Riot:v3.6.1
axios:v0.16.2


axiosをダウンロードし、axios.min.jsをwww/js/axios.min.jsに配置しておきます。




サーバー側のプログラム



jsonデータを返却するプログラムはpythonのcgiで作成しました。
Python 組み込みのCGIHTTPServerやhttp.serverでcgiを動かす

適当にこんなプログラムを作成。

・cgi-bin/sample.py


  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. import json
  4. import cgi
  5. import cgitb
  6. cgitb.enable(display=0, logdir='./')
  7. print('Access-Control-Allow-Origin: *')
  8. print('Content-type: text/javascript; charset=UTF-8\r\n')
  9. # 送信データの先頭に「echo」をつけて返却
  10. result = [
  11.     {"id" : 1, "name" : "一番"},
  12.     {"id" : 2, "name" : "二番"},
  13.     {"id" : 3, "name" : "三番"},
  14.     {"id" : 4, "name" : "四番"},
  15.     {"id" : 5, "name" : "五番"}
  16. ]
  17. print(json.dumps(result))




実行権限を付与して、cgiサーバーを起動します。


$ chmod +x cgi-bin/sample.py
$ python3 -m http.server --cgi







アプリケーション



サンプルを見様見真似でプログラムを作成してみます。

・www/index.html


  1. <!DOCTYPE html>
  2. <html>
  3.     <head>
  4.         <meta charset="utf-8" />
  5.         <meta name="format-detection" content="telephone=no" />
  6.         <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height" />
  7.         <link rel="stylesheet" href="css/phonon.css" />
  8.         <title>App</title>
  9.     </head>
  10.     <body>
  11.         
  12.         <!-- Panel tags go here -->
  13.         <!-- Side Panel tags go here -->
  14.         <!-- Notification tags go here -->
  15.         <!-- Dialog tags go here -->
  16.         <home data-page="true"></home>
  17.         <pagetwo data-page="true"></pagetwo>
  18.         <!-- page tags -->
  19.         <script src="tags/home.tag" type="riot/tag"></script>
  20.         <!-- scripts -->
  21.         <script src="js/riot+compiler.min.js"></script>
  22.         <script src="js/axios.min.js"></script>
  23.         <script src="js/phonon.js"></script>
  24.         <!-- our app config -->
  25.         <script src="js/app.js"></script>
  26.     </body>
  27. </html>





・www/js/app.js


  1. phonon.options({
  2.     navigator: {
  3.         defaultPage: 'home',
  4.         animatePages: true,
  5.         enableBrowserBackButton: true,
  6.     },
  7.     i18n: null
  8. });
  9. var app = phonon.navigator();
  10. app.on({page: 'home', preventClose: false, content: null});
  11. app.start();





・www/tags/home.tag


  1. <home>
  2.     <header class="header-bar">
  3.         <div class="center">
  4.             <h1 class="title">Phonon+Riot</h1>
  5.         </div>
  6.     </header>
  7.     <div class="content">
  8.         <ul class="list">
  9.             <li class="divider">一覧表示</li>
  10.             <li each={ items }>
  11.                 {id}:{name}
  12.             </li>
  13.         </ul>
  14.     </div>
  15.     <script>
  16.         var self = this
  17.         self.items = []
  18.         this.on('create', function() {
  19.             axios.get('http://192.168.1.4:8000/cgi-bin/sample.py')
  20.                 .then(function (response) {
  21.                     self.update({items : response.data})
  22.                 }).catch(function (error) {
  23.                     console.log(error)
  24.                 });
  25.             
  26.         })
  27.     </script>
  28. </home>





最終的にディレクトリの構成はこのようになります。

759_01.png


エミュレーターを起動してみると


$ cordova emulate android




動いてくれました。

759_02.png

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/07/29(土) 18:04:56|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
前のページ 次のページ