月別アーカイブ 7月 2019

asaba 著者:asaba

【react】ListItemSecondaryActionが参照できない

material-uiを使ってリストビューみたいなのを作ろうと思ったら読み出し先が違うらしいエラーが出ました。

以下のような英文です。

 

invariant.js:38 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined

 

多分、material-uiにはアイコンとかを収納している箱みたいのがあって本来その箱には存在しないuiを取ってこようとしている

ので怒っているんだと思います。いやいや公式ですけど!!!(# ゚Д゚)

 

 

例えば、

import { List, ListItem, ListItemSecondaryAction, ListItemText } from “material-ui/List”;
この中のListItemSecondaryActionも確かListItemとかと同じカテゴリで参照先は同じはず・・・。なのに
実装しようとしたら無いとか言われる始末。あかんこれどれ信用していいかわかったもんじゃありません。
バージョンアップとかが必要になったら書き換えとかどちゃくそめんどくさそうなので手を出さずに自前でcssで作った方が
早いかもしれません。(他に方法があるのでしょうがバージョンアップとかして仕様が変わっているのが怖いので手を出しません。)
他にも試してみると、アイコン系は全部このエラーが出てしまいました・・・。解決策はなんとかしてuiの参照先を
見つけるしかないみたいですね。
ちなみに公式で書いてあるimport IconButton from ‘@material-ui/core/IconButton’;みたいな書き方だと100%エラーになります。
インチキ参照もいいかげんにしろといいたいですけど上手くできないのは今の自分の技術不足ということでのんでおきます。
※追記 無事参照出来ました。
import ListItemSecondaryAction from “material-ui/List”;で単独でインポートして解決。
  • この記事いいね! (0)
村上 著者:村上

【Cordova】「phonegap-plugin-csdk-image-editor」プラグイン導入時に遭遇したエラーの対処法

今回は、Cordova のプラグイン「phonegap-plugin-csdk-image-editor」を導入しようとした際に遭遇したエラーです。
なお、現在も違うエラーに苦戦中…。
…既存のコードを修正したほうが早いかもしれません。

エラーメッセージは「java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/os/AsyncTaskCompat;」です。
ちなみに、Android Studio で実行した際表示されたエラーメッセージ冒頭に書かれているエラーは「java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/os/BuildCompat;」でしたが、そちらではなく「java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/os/AsyncTaskCompat;」で検索したところ有効な記事にたどり着けました。

今回参考にさせていただいた記事はこちら。

android – java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/os/BuildCompat – Stack Overflow
https://stackoverflow.com/questions/39601370/java-lang-noclassdeffounderror-failed-resolution-of-landroid-support-v4-os-bui

 

で、対処法ですが、「support/v4/os/AsyncTaskCompat」関連のファイルが参照できないことが問題なので、手動で追加すればOKです。
下記の画像のように、java ディレクトリの直下に android.support.v4.os というディレクトリを作成します。

あとは、作成したディレクトリ内に、AsyncTaskCompat.javaAsyncTaskCompatHoneycomb.java のファイルを下記のコードで作成します。

AsyncTaskCompat.java

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.support.v4.os;
import android.os.AsyncTask;
import android.os.Build;
/**
 * Helper for accessing features in {@link android.os.AsyncTask}
 * introduced after API level 4 in a backwards compatible fashion.
 */
public final class AsyncTaskCompat {
    /**
     * Executes the task with the specified parameters, allowing multiple tasks to run in parallel
     * on a pool of threads managed by {@link android.os.AsyncTask}.
     *
     * @param task The {@link android.os.AsyncTask} to execute.
     * @param params The parameters of the task.
     * @return the instance of AsyncTask.
     */
    public static <Params, Progress, Result> AsyncTask<Params, Progress, Result> executeParallel(
            AsyncTask<Params, Progress, Result> task,
            Params... params) {
        if (task == null) {
            throw new IllegalArgumentException("task can not be null");
        }
        if (Build.VERSION.SDK_INT >= 11) {
            // From API 11 onwards, we need to manually select the THREAD_POOL_EXECUTOR
            AsyncTaskCompatHoneycomb.executeParallel(task, params);
        } else {
            // Before API 11, all tasks were run in parallel
            task.execute(params);
        }
        return task;
    }
    private AsyncTaskCompat() {}
}

AsyncTaskCompatHoneycomb.java

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.support.v4.os;
import android.os.AsyncTask;
/**
 * Implementation of AsyncTask compatibility that can call Honeycomb APIs.
 */
class AsyncTaskCompatHoneycomb {
    static <Params, Progress, Result> void executeParallel(
            AsyncTask<Params, Progress, Result> task,
            Params... params) {
        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
    }
}

上記 2つのファイルが作成出来たら、アプリを一度 Clean してから Build → 実行してください。
私の環境では、問題なく動作しました!

 

以上、「phonegap-plugin-csdk-image-editor」プラグインを導入時に遭遇したエラー「java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/os/AsyncTaskCompat;」の対処法でした。
「phonegap-plugin-csdk-image-editor」プラグインの導入方法そのものについては、後日ご紹介する予定です。

  • この記事いいね! (0)
takahashi 著者:takahashi

確かにSIMフリーのAndroid端末でも防災速報が受信できた話

先日の大雨は久々に不安を感じるレベルでした。

側溝から水が噴水のようにあふれていたり、道路に水が冠水してしまっていたり、極めつけは普段名前の聞かないような川の周辺まで警報が出て、ちょっと恐怖を感じました。

冠水こそありましたが、川の氾濫という最悪の自体がギリギリ回避できて、ほっとしました。

ところで、先日SIMフリーのAndroid端末でも、Android8.1から標準で緊急速報が受信できるようになったという話をご紹介しました。

こちらの記事ではIIJ社が行った実験による緊急速報の受信の様子をご紹介しましたが、実際に今回の増水による避難勧告発令時に、自分が所有するPixel 3a(Android 9)でも実際に緊急速報を受信することができました。

実際にはこのような画面になりました。

前回ご紹介したIIJ社の実験の通り、最初に内容のない緊急速報を受信し、そのすぐ後に詳細な内容を受信しました。

以前使っていたXperia Z5(Softbank版 Android 6)では警報を受信しても専用の通知音がなるだけでしたが、Pixel 3aの場合は通知音が流れた後、内蔵の読み上げエンジンで全文が音声で読み上げられるようになっていました。

これはロック画面を解除していない状態でも行われ、スマホを開くことなく警報内容を確認することができるので、安心できます。

この機能はAndroid 8.1以降のAndroidには標準で含まれているため、SIMフリーであってもモバイル回線に接続されていればメーカーやキャリア側で意図的に無効化されない限りは8.1以降のすべてのAndroidで受信できそうです。

いままで、こういった重要な機能が搭載されていないといった理由でSIMフリー版のスマホを購入がちょっと心配になるパターンもあったのですが、今後はそういった縛りを受けることなく機種を選ぶことができそうなのはとてもありがたいですね。

  • この記事いいね! (0)
asaba 著者:asaba

【javascript】クロージャは即時関数で囲むとより効果的

今回はクロージャを使っている中で少し躓いたことを綴ります。

クロージャとは、関数の中に関数が入っている状態のことを指し、スコープ内の変数を関数に渡したい時によく使われます。

javascripterにとっては基本中の基本ですが、恥ずかしいことに下のような間違いを犯してしまい手こずる羽目に・・・。

 

</pre>
document.body.onload = addElement;
var json = {
ハンバーグ: {
分類: '今日はハンバーグを食べました。ボリューム満点!',
主成分: 'タンパク質'
},
カレー: {
分類: '暑い夏には激辛カレーが一番!',
主成分: '炭水化物'
},
親子丼: {
分類: 'ふわふわトロトロ懐かしの味!',
主成分: 'タンパク質'
}
};
function addElement () {
for (var item in json) {
// 新しい div 要素を作成します
var newDiv = document.createElement("div");
// いくつかの内容を与えます
var newContent = document.createTextNode(json[item]['分類']);

newDiv.addEventListener('click', function() {
sample (json[item]['主成分']);
}, false);

// テキストノードを新規作成した div に追加します
newDiv.appendChild(newContent);

// DOM に新しく作られた要素とその内容を追加します
var currentDiv = document.getElementById("div1");
document.body.insertBefore(newDiv, currentDiv);
}
}
function sample (e) {
var component = e;
console.log(component);
}
<pre>

 

addEventListenerの中の関数にjsonの要素を指定しています。本来ならば順に「タンパク質」「炭水化物」「タンパク質」と

出したかったのですが、生成されたdivの中身をクリックすると全ての要素に一番最後の「主成分」要素である「タンパク質」

が格納されてしまっています。

これは、格納しようとした値が保持できないために起きる事故です。

この場合は即時関数で実引数にjson要素を持たせればちゃんと値を保持したまま回ってくれます。

もっと沼るかと思いましたが即時関数のことを知っていたのでさくっと直すことが出来ました。

正しくはこんな感じです↓

 

</pre>
(function(n) {
newDiv.addEventListener('click', function() {
sample (n);
}, false);
})(json[item]['主成分']);
<pre>

 

reactをやっている限りはまあ使うことはないと思いますが(mapがありますしね)生のjavascriptを触るうえで覚えておくと

クロージャと即時関数まとめて理解できるので損はないと思います~。

 

  • この記事いいね! (0)
村上 著者:村上

【JavaScript】Ajaxを使わない非同期通信処理「XMLHttpRequest」の書き方

自分のための備忘録としてまとめ。
Ajax のかわりに XMLHttpRequest を使って非同期通信の処理を行う方法です。
普段、Ajax に頼りきりで、書き方をすっかり忘れていたので、今後のためにまとめておきます。

今回参考にさせていただいた記事はこちらから。

XMLHttpRequestによるPOSTメソッド|JavaScript プログラミング解説
https://so-zou.jp/web-app/tech/programming/javascript/ajax/post.htm

JavaScript によるフォームの送信 – Web 開発を学ぶ|MDN
https://developer.mozilla.org/ja/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript

 

早速ですが、サンプルコードは下記のとおりです。
なお、サンプルは POST の場合の書き方です。

// POSTメソッドで送信するデータ
var data = { param1: 'abc', param2: 100 }; 
var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest .addEventListener('load', function(event) {
    // データが正常に送信された場合の処理
});
xmlHttpRequest .addEventListener('error', function(event) {
    // エラーが発生した場合の処理
});
xmlHttpRequest.open('POST', '[送信先URL]');
// サーバに対して解析方法を指定する
xmlHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// データをリクエスト ボディに含めて送信する
xmlHttpRequest.send(EncodeHTMLForm(data));

一緒に送信したいデータは、変数 data に代入し、14行目で送付しています。
ただし、送信するデータは HTML フォームの送信に使用される形式に変換する必要がありますので、下記の関数でエンコードする必要があるとのことでした。

function EncodeHTMLForm(data) {
    var params = [];
    for(var name in data) {
        var value = data[ name ];
        var param = encodeURIComponent(name) + '=' + encodeURIComponent(value);
        params.push(param);
    }
    return params.join('&').replace(/%20/g, '+');
}

うっかりこの処理を抜いて実行したところ、当然ながら正しく値が渡せていなかったため、ご注意ください。

送信完了時の処理と、エラーが発生した時の処理は、それぞれ 4行目と 7行目の関数内で定義します。
ステータスコードなどで判断する方法もありましたが、こちらの方がコードがすっきりとしていて好みなので、こちらの書き方を採用しました。

 

以上、Ajax を使わずに非同期通信処理を行う方法でした。
ご参考になれば幸いです。

  • この記事いいね! (0)
著者:杉浦

【PHP】関数implodeの引数が類を見ないくらい自由だった話

 文字列の結合と分割はよく行われる操作であり、PHPにもそのための組み込み関数implode, explodeが用意されています。
PHP: implode – Manual
PHP: explode – Manual
 それぞれドキュメント上では次の様な呼び出し方が説明されています。

implode ( string $glue , array $pieces ) : string
implode ( array $pieces ) : string
explode ( string $delimiter , string $string [, int $limit = PHP_INT_MAX ] ) : array

 第一引数に区切り文字、第二引数に対象が入るのだな、と理解できます。しかしこのimplode実は次の様にも動きます。

 第二引数に対象、第一引数に区切り文字でも動きます。暗黙の内によしなにしてくれるのはPHPあるあるですが流石にこれは凄まじいです。ちなみにexplodeはダメです。公式で次の様に注意喚起されています。

注意:

歴史的理由により、implode()
はいずれのパラメータ順も受け入れることができますが、
explode() はそうできません。
string 引数の前に必ず
delimiter 引数がくるように確認する必要があります。

あまりにも自由すぎたのかPHP7.4から非推奨になります。RIP.
PHP: rfc:deprecations_php_7_4#implode_parameter_order_mix

  • この記事いいね! (1)
著者:ym

CDNで使用されるSSLとSANs

CDN やレンタルサーバでは他社とサーバやポート番号を共有ことが多くあります。最近では SSL/TLS の処理も必要になるので、443 番ポートを共有し、SNI に対応した Web サーバで処理することが普通かと思います。

しかし SSL/TLS 証明書まで共有している例は初めてみました。www.nikkei.com が採用している CDN では SSL/TLS 証明書まで共有している様です。確かに DV 証明書であれば問題は無いですが、この証明書は OV 証明書ですよね?認証上はドメイン使用承諾している状況かな。
SANs (Subject Alt Name)へ共有しているコモンネームが網羅されるので、結構気になるんですよね。

あれ?CN(コモンネーム)違うじゃん O(組織) が Fastly ? 他社じゃん。やべっ・・・。って、びっくりしました。
こうやって、SSL証明書を見て、本当に接続したサイトは正サイトと確認している人もいるので、どうかと思うんですよねぇ。

SSL証明書の発行日を見ると、2019年7月18日、つい先日更新している様子ですが、以前からなのかな。

  • この記事いいね! (0)
asaba 著者:asaba

【react】react-tagcloudの使用感について

snsでバズっているワードをタグクラウドで出したくてjqueryとかで色々探していたのですがjqueryプラグイン

同士の競り合いを起こしたり古いバージョンのjqueryが必要だったりとやたらと面倒だったのでnpmの

react-tagcloudというプラグインの力を少しお借りしました。

名前の通りreact向けにタグクラウドを生成してくれるnpmのパッケージで、規約(決まったコード)が少ない

ので比較的自由度が高く少しのアレンジでタグクラウドをカスタマイズすることができます。

 

</pre>
--------render------

const values = ["like vegetable", "like meet", "like fish"];
const data = [];
for(i=0; i < values.length; i++){
data[i] = { value: values[i], count: 5 };
};

--------return-------

<TagCloud minSize={5}
maxSize={35}
tags={data}
onClick={tag => this.tagClick(`'${tag.value}'`)} />
<pre>

 

これは配列に格納した値を順にTagCloudのプロパティに設定するだけのコードです。

(自作ですがconosle.logで最終的に値を取れたので載せておきます)

render内でdata[i] = { value: values[i], count: 5 };と二つのオプションがありますが、valueは

タグにしたい文字列、countはタグの大きさを指定しています。20でもかなり大きいので10前後にして

おいたほうが見栄えがいいかもです。

 

次にTagCloud内の説明になりますが、tags={data}で上でぶん回した配列の値を指定しています。

onClickの書き方がちょっと特殊で処理内に`’${tag.value}’`と書いてありますが

これは格納してあったタグの値つまり”like vegetable”, “like meet”, “like fish”を指定しており、処理も

値別に分けることができます。

 

簡単な説明ですが以上になります。

このコード量でタグクラウドの基本的な動きを抑えられるので、ブラウザで化けなければ採用できるかもです。

タグクラウドのプラグインの中でも一番わかりやすくて余計なことが書いていないので、同じような

機能を探している人におすすめのプラグインです。

 

  • この記事いいね! (0)
村上 著者:村上

【Android】「Duplicate class android.support.v4.app.INotificationSideChannel found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:27.0.2)」エラーの対処法

長々としたタイトルですが、今回は Android Studio で発生したエラーについてです。
なお、ネイティブアプリではなく、Cordova で開発したアプリです。
エラーメッセージはもっと長かったので割愛します。

今回参考にさせていただいた記事はこちらから。

gradle – Duplicate class android.support.v4.app.INotificationSideChannel found in modules classes?
– Stack Overflow

https://stackoverflow.com/questions/55909804/duplicate-class-android-support-v4-app-inotificationsidechannel-found-in-modules/55932544

こちらの記事にはエラーメッセージが掲載されていますが、まさしくこのような感じのメッセージでした。
そしてこれだけでは何をどう直していいのかが分からない…。

 

さて、解決方法ですが、gradle.properties というファイルに下記の 2行を追加するだけです。

android.useAndroidX=true
android.enableJetifier=true

ただ、私の環境では gradle.properties がなかったので、作成してから追加しました。
なお、作成するときは、プロジェクト直下のファイルを右クリックし、表示されたメニューの New > File から作成しました。
画面イメージは下の画像のとおりです。

あとは、普段通りビルドをしたところ、発生していたエラーが解消されました。

…が、あとになって、不要なプラグイン「cordova-plugin-firebase」を削除して再度実行したところ、エラーそのものが発生しなかった模様…。
たまにやってしまうのですが、不要なプラグインはすぐに消すようにしたほうが良さそうですね。

 

以上、Android Studio で発生したエラーの対処法でした。
エラーメッセージが長い&意味がわかりにくいのでとりあえず検索しましたが、有効な解決方法がヒットしてよかったです。
ご参考になれば幸いです。

  • この記事いいね! (0)
著者:杉浦

【Vue】改行とv-htmlとXSS対策

 Vue.js上で文字列を展開したい時があります。例えばそれは誰かが投稿したコメントをコンポーネント上に表示する時です。こういった時コメントの改行が反映されていない場合、見栄えが悪くなります。改行を行う必要があります。
 HTML上の改行と言えばbrタグです。PHPにはnl2brという改行コードを改行タグに変換する組み込み関数があるぐらいです。
PHP: nl2br – Manual
 改行の実現でありがちで危険なアンチパターンはこのnl2br関数を用いたコメントをそのまま表示しようと考えるものです。Vue.jsにはv-htmlというディレクティブがあり、これを用いると普段かかっている安全装置のHTMLエスケープを外し、HTMLとしてパース、実行します。brタグとv-htmlを用いることで改行コードを改行タグに変換して表示できます。
 v-htmlはXSSをまあまあ容易に招く危険性を持ちます。まあまあ危険というのは単純な

<script>alert('XSS')</script>

ぐらいならVueの仕組み上実行されず済むからです。とはいえ

<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED>

の様な多少の変化球(scriptタグをbase64形式でエンコード、埋め込んだコード中でデコードして実行)であっさり破られるのでやはり危険です。

XSS 脆弱性を容易に引き起こすので、ウェブサイトで動的に任意のHTMLを描画することは、非常に危険です。信頼できるコンテンツにだけ HTML 展開を利用してください。ユーザーから提供されたコンテンツに対しては決して使用してはいけません。

テンプレート構文 — Vue.js

 これの対策は実現したい機能に関しての実装を生のHTMLに頼るのでなく個々の別手法を用いるのが一番でしょう。
 例えば改行に関してはCSSのwhite-space実現できます。white-spaceは要素内のホワイトスペースをどう扱うか決定するスタイルであり、ホワイトスペースの一種(少なくとも正規表現の\sグループでまとめられる)である改行文字の制御もこれでできます
white-space – CSS: カスケーディングスタイルシート | MDN
 上記リンクから引用した次の表の’改行を残す’スタイルを用いれば
と生のHTML実行を用いるまでもありません。

  改行 空白とタブ文字 テキストの折り返し 行末の空白
normal まとめる まとめる 折り返す 除去
nowrap まとめる まとめる 折り返さない 除去
pre 残す 残す 折り返さない 残す
pre-wrap 残す 残す 折り返す ぶら下げ
pre-line 残す まとめる 折り返す 除去
break-spaces 残す まとめる 折り返す 折り返す
  • この記事いいね! (0)