20190503のHTMLに関する記事は3件です。

metaタグを用いたリダイレクト機能で躓いた件

#概要
HTMLにおける<meta>タグを使用した
リダイレクト機能をテストした際に
指定URLに飛ばずに四苦八苦し記録です。

背景

基礎からのMySQLを進める途中、
まさにその基礎勉強に飽き飽きし、
PHPの学習に飛んだ時の話です。

phpの話に入ったばかりの課題が
表題の件でした。
(最初にやることじゃなくね…?)

開発環境

MacOS Mojave
PHP 7.1.23
Apache 2.4.39
使用ブラウザ Safari

内容

初期に書いたコードは以下の通りでした。
文法は「基礎からのMySQL」に基づいていますが、
ちょっとだけアレンジしています。

test.php
<?php
print "<head>";
print " <meta http-equiv='refresh' content=5; URL='http://www.softbank.jp/'>";
print "</head>";
print "<body>";
print "5秒後にソフトバンクのページへ移動します";
print "</body>";
?>

何とも言えないクソコードですね。
出力結果を見てみましょう。

5秒後にソフトバンクのページへ移動します

↓5秒後…

5秒後にソフトバンクのページへ移動します

ページは変わらず、永遠と5秒ずつ同じページを
更新し続けています。
書籍の説明では、5秒後に
指定したURL先にジャンプするはずなのですが…

対処

ググりにググり、リダイレクト機能について調査
しましたが、ほとんどのサイトが上記の記述で
説明されていました。

ところが、ある一つのサイトだけ
違った記述方法でした。

その記述方法を用いて訂正したコードを
下記に示します。

test.php
<?php
print "<head>";
//シングルクオートの位置が違う
print " <meta http-equiv='refresh' content='5; URL=http://www.softbank.jp/'>";
print "</head>";
print "<body>";
print "5秒後にソフトバンクのページへ移動します";
print "</body>";
?>

訂正前はURLのみをシングルクオートで囲っていましたが

訂正前
<meta http-equiv='refresh' content=5; URL='http://www.softbank.jp/'>

訂正後はcontentで指定する秒数の前からシングルクオートで
囲っています。

訂正後
<meta http-equiv='refresh' content='5; URL=http://www.softbank.jp/'>

結果、出力は以下の通りになりました。

5秒後にソフトバンクのページへ移動します

↓5秒後…

(ソフトバンクホームページ)

成功しましたね。

結局何が原因なの?

現時点で分かっていません。
教えてエロい人。

参考書籍

基礎からのMySQL
参考サイト

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

FacebookシェアにOGPが反映されない(Let's Encryptの中間証明書)

あるサイトにて、FacebookでのシェアのときにOGPが反映されないことがあり、いろいろ調べたのでメモ。

SSL/TLS関連のエラー

SSL/TLSの設定にエラーがあると(一見するとちゃんとhttpsでアクセスできていたとしても)、シェア時にエラーになりOGPが反映されないらしい。
勉強を兼ねて自分でLet's EncryptでSSL/TLSを設定したサーバだったので、いろいろ不備があったらしい。

環境

  • AWS EC2
  • Amazon Linux
  • Apache/2.4.39
  • Let's Encrypt

対処内容

正直なところ、「こうやったらできた。」というだけで、すべて理解しているわけではないので注意。

関連するプログラムをアップデート

$ sudo yum update openssl
$ sudo yum update httpd

中間証明書

どうも中間証明書が設定されていないとだめ?っぽいエラーがでていたので、設定してみる。
ssl.confを開いて編集する。

$ sudo vi /etc/httpd/conf.d/ssl.conf
ssl.conf
SSLCertificateChainFile /etc/letsencrypt/live/xxx.xxxxxx.xx/chain.pem

上記の場所を探してコメントアウトして chain.pem の場所を設定。
(xxx..のところは、SSLの対象ドメイン名と同名のディレクトリ)
自分の場合は、そのままコメントアウトすればOKでした。

上記を書き換えて、Apach再起動したら、ちゃんとシェアしたときにOGPが反映されるようになりました。

$ sudo service httpd reload

ただ、かなり手探りなのと知識不足も有り、これが正しい方向かはまだ不安があります。

参考サイト

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.jsのv-htmlで書き出したHTMLを非同期的にjQueryで更新する

goal.gif

Vue.jsのv-htmlで書き出したHTMLを非同期で書き換えてみましょう。
サンプルではユーザーの入力した文字をv-htmlで表示しています。

書き出したHTMLにimgが含まれていた場合、imgのdata-nameを元に非同期で画像データを引っ張ってきて表示する、という想定です。
(画像データを用意すると一手間かかるため、今回は代わりに絵文字を表示しています。)

自己紹介
アプリクリエイターの ミャウチー です。HTMLとCSS歴は8年になります。
アプリを作っている最中に今回の問題にぶつかって自己解決したので、ノウハウを共有します。

今回の前提条件
HTML, CSS, JavaScriptを使います。
初歩レベルのjQueryを使います。
Vue.jsは data: { 〜 }@click が分かっている前提です。
Vue.jsはCDNで実行しています。

もくじ
1. 初期状態の確認
2. Vueデータに変更があったときアラートを出す
3. v-htmlで書き出されたときアラートを出す
4. 書き出されたHTMLを取得して非同期処理をする
5. 待機中に [loading...] を出す

注意
今回作成するものは、非同期である必要のない処理を非同期に実行しています。
今回の目的が「Vue.jsのv-htmlで書き出したHTMLを非同期的にjQueryで更新する」であり、問題を単純化するためです。
実際の場面では今回の例を応用して、何かしらのAPIを非同期で実行することを想定しています。


先に完成形のコードをみたい方は、この行をクリックすると下に展開されます。

HTML:

<main>
    <input type='text' v-model='input'>
    <input type='button' value='↓' @click="output = input"> HTML
    <p v-html='output'></p>
</main>

CSS:

img[src='']::before {
    content: "[ loading... ]";
}

JavaScript:

const vm = new Vue({
    el: 'main',

    data: {
        input: '',
        output: '',
    },

    watch: {
        output: function(val) {
            const $dom = $(this.$el)

            this.$nextTick(function() {
                // 非同期的な何かしらの処理
                setTimeout(function() {

                    // data-nameで指定した値を取得
                    const name = $dom.find('img').data('name')

                    // 今回は簡易例として画像を絵文字に置き換えます
                    const character = (name === 'cat') ? '?' : '?'
                    $dom.find('img').replaceWith(`<span>${character}</span>`)

                    // APIで取得した画像などを表示する場合はこちら
                    //$dom.find('img').attr('src', "https://〜画像のURL〜.jpg")

                }, 2000)    // = 例として2秒後に実行
            })
        },
    },
})


STEP 1 初期状態の確認

01.gif

HTML:
・ユーザーの入力ボックス
・反映ボタン
・HTMLを書き出す領域
HTMLはこれ以上変更しません。

<main>
    <input type='text' v-model='input'>
    <input type='button' value='↓' @click="output = input"> HTML
    <p v-html='output'></p>
</main>

CSS:
空っぽの状態から始めます。

/* なし */

JavaScript:

const vm = new Vue({
    el: 'main',

    data: {
        input: '',
        output: '',
    },
})

実行の流れ:
1. 変数inputにユーザーの入力した文字が入る
(例: hello <img data-name='cat' src=''> world!
2. 「↓」ボタンを押すと 変数output = input となる
3. 変数outputがHTMLとして書き出される
(書き出されたとき<img〜>が表示されないのは、src属性が空っぽなためです。)

STEP 2 Vueデータに変更があったときアラートを出す

02.gif

new Vue({ 〜 }) 内の一番下に次のコードを足します。

watch: {
    output: function(val) {
        alert("outputの中身が変わりました")
    },
},

output の変更をwatchすることで、変更があったときに関数が実行されます。

STEP 3 v-htmlで書き出されたときアラートを出す

03.gif

output: function(val) { 〜 } を次のように書き換えます。

output: function(val) {
    this.$nextTick(function() {
        alert("HTMLが書き出されました")
    })
},

$nextTick() は、DOMが書き換えられた後に呼び出されます。
参照:Vue.js リアクティブの探求 #非同期更新キュー

体感的にはalertの出るタイミングがSTEP 2の時と変わりないですが、若干違います。
STEP 2のとき:DOMが書き換えられる前
STEP 3のとき:DOMが書き換えられた後
(alertと同じタイミングで console.log(this.$el.innerHTML) などとDOMの中身をコンソール出力してみると分かりやすいです)

STEP 4 書き出されたHTMLを取得して非同期処理をする

04.gif

STEP 4 - 1
output: function(val) { 〜 } 内の一番上に const $dom = $(this.$el) を書き足します。

変数$domには、v-htmlで書き出されたHTMLを含むjQueryオブジェクトが代入されます。
(厳密には、今回の場合 $dom[0] === $('main')[0] です。)

STEP 4 - 2
this.$nextTick(function() { 〜 }) の中に非同期的な何かしらの処理を書きます。
今回は例として、DOMが変更された2秒後にimgを絵文字に置き換えます。

this.$nextTick(function() {

    /* * * 非同期的な何かしらの処理 * * */
    setTimeout(function() {

        // data-nameで指定した値を取得
        const name = $dom.find('img').data('name')

        // 今回は簡易例として画像を絵文字に置き換えます
        const character = (name === 'cat') ? '?' : '?'
        $dom.find('img').replaceWith(`<span>${character}</span>`)

        // APIで取得した画像などを表示する場合はこちら
        //$dom.find('img').attr('src', "https://〜画像のURL〜.jpg")

    }, 2000)    // = 例として2秒後に実行
})

STEP 5 待機中に [loading...] を出す

05.gif

DOMが書き出されてから絵文字が表示されるまでの間、代わりの文字を出しておきます。

今回は imgタグのsrc属性が空っぽ のとき、画像の代わりに [ loading... ] を表示します。
例: <img src=''>

CSS:

img[src='']::before {
    content: "[ loading... ]";
}

まとめ

goal.gif

今回はVue.jsのv-htmlで書き出したHTMLを非同期で書き換えました。
応用としては、画像データを何かのAPIで非同期に取得したいときに使えるかと思います。

私の場合、Firebase Firestoreから文書データを引っ張ってきたときに、テキストデータをまず先に表示して、画像が含まれていたらFirebase Storageから非同期に取得する、としようとしました。
それで今回のことが分からずつまずき、「Vue.js リアクティブの探求 #非同期更新キュー」を解読しながら自己解決したので、共有しました。

実際にv-htmlを使う場合は「Vue.js テンプレート構文 #生の HTML」に書かれている通り、XSSに気をつけてください。

HTML:

<main>
    <input type='text' v-model='input'>
    <input type='button' value='↓' @click="output = input"> HTML
    <p v-html='output'></p>
</main>

CSS:

img[src='']::before {
    content: "[ loading... ]";
}

JavaScript:

const vm = new Vue({
    el: 'main',

    data: {
        input: '',
        output: '',
    },

    watch: {
        output: function(val) {
            const $dom = $(this.$el)

            this.$nextTick(function() {
                // 非同期的な何かしらの処理
                setTimeout(function() {

                    // data-nameで指定した値を取得
                    const name = $dom.find('img').data('name')

                    // 今回は簡易例として画像を絵文字に置き換えます
                    const character = (name === 'cat') ? '?' : '?'
                    $dom.find('img').replaceWith(`<span>${character}</span>`)

                    // APIで取得した画像などを表示する場合はこちら
                    //$dom.find('img').attr('src', "https://〜画像のURL〜.jpg")

                }, 2000)    // = 例として2秒後に実行
            })
        },
    },
})

質問や気になる点があれば、コメントやTwitterで連絡ください!

ミャウチー

高校一年の頃からアプリ作りに没頭していて、今はアプリクリエイターとしての人生を主軸に生きています。
おじいさんになっても縁側に座ってカタカタとアプリ作りをします。最近はアウトプットを大切にしようと奮闘中です。
サイバーブレイン株式会社( メインサービスはAI Academy )でデザイナーをしています。

Twitter | Miyauchi Akira
https://twitter.com/miyauchoi

portfolio.png
ポートフォリオ | ミヤウチアキラ
https://miyauchi-akira.app

note.png
アプリデザインで考えていること
「ポエティカルデザイン」というアプリデザイン手法 | note

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む