html5.2から追加された属性と属性値について

<h1>最新html5.2から追加された属性と属性値</h1>
今回は、htmlの最新バージョンであるhtml5.2から追加された、属性と属性値についてまとめました。

<li>1.<a href="#allowpaymentrequest">allowpaymentrequest属性</a></li>
<li>2.<a href="#canonical">canonical属性値</a></li>
<li>3.<a href="#noreferrer">noreferrer属性</a></li>
<li>4.<a href="#apple-touch-icon">apple-touch-icon</a></li>
<li>5.<a href="#douwnload">douwnload属性</a></li>
<h2 id="allowpaymentrequest">allowpaymentrequest属性</h2>
iframeにPayment Request APIを使うためのallowpaymentrequest属性が追加iframeでPayment Request APIの実行を許可する場合に、allowpaymentrequest属性を設定することで利用できるようになりました。 
Payment Request APIはweb上でのクレジット決済機能など支払いを行うための機能で、本機能はiframe内でもそれらを実行するためのものになります。
ですが、この属性調べてみると、HTML5.2で追加されましたが現行の仕様から削除されています。
<h3>代替方法</h3>
<p>“allow”属性を使用します。allow 属性は Feature Policy 仕様に基づき値を指定することで、ユーザエージェントにおける特定の機能や API を有効化、あるいは無効化したり、動作を変更したりすることができます。属性値をpaymentにし、以下の許可リストを指定して、有効、無効にしていきます。</p>

| 許可リスト | 効果 |
| :---- |:----|
| * |すべてのオリジンで許可|
| 'self' |埋め込まれた文書が最上位のブラウジング・コンテキストと同じオリジンの場合は許可|
| 'src' |埋め込まれた文書が“src”属性で指定したURLと同じオリジンの場合は許可|
| 'none' |すべてのオリジンで拒否|
| オリジン |特定のオリジンのみ許可する|

<記述方法>
無効（allow="payment 'none'"）

```html
<iframe src="html.html" allow="payment 'none'" style=" width: 500px; height: 300px;"></iframe>
```

有効（allow="payment *"）

```html
<iframe src="html.html" allow="payment *" style=" width: 500px; height: 300px;"></iframe>
```

実装例を作ったのですが、Payment Request API は https//から始まるサイトでしか使用できず、今回テストページは載せられませんが、ローカルホストでならPayment Request API は使用できるみたいなので、そちらの方法を共有いたします。

```html
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Payment API</title>
  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
  <link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
  <script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>
  <script src="https://storage.googleapis.com/prshim/v1/payment-shim.js"></script>
  <style>
    body {
      display: flex;
      align-items: center;
      justify-content: center;
    }
  </style>
  <script>
    window.onload = function () {
  var $btn = document.getElementById('btn');
  $btn.addEventListener('click', onBuyClicked, false);
}

function onBuyClicked() {
  if (!window.PaymentRequest) {
    location.href = '/checkout';
    return;
  }

  var supportedInstruments = [{
    supportedMethods: ['basic-card'],
    data: {
      supportedNetworks: [
        'visa', 'mastercard', 'amex', 'discover', 'diners', 'jcb', 'unionpay'
      ]
    }
  }];

  var details = {
    displayItems: [
      {
        label: '通常商品',
        amount: { currency: 'YEN', value: '10000' }
      },
      {
        label: 'クーポン',
        amount: { currency: 'YEN', value: '-2000' }
      }
    ],
    total: {
      label: '合計',
      amount: { currency: 'YEN', value: '8000' }
    }
  };

  var request = new PaymentRequest(supportedInstruments, details);
  request.show();
}
  </script>
</head>
<body>
  <button id="btn" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">お支払い</button>
  <script src="js/script.js"></script>
</body>
</html>
```
そして作成したページを、以下のように　iframe で指定するだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941859/4957e2b0-5cf0-b50b-50c0-a073180368ea.png)
お支払いボタンを押下すると下記の画像が出てくるものと出てこないものがあります。
![スクリーンショット 2021-01-08 4.37.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941859/519735c7-7565-a025-b80d-8a8ef32fbd97.png)
<サポート状況>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941859/95e068cf-9758-a725-34b9-c8689d2f939f.png)
￼
これだけ見ると、ブラウザーの対応はまだ進んでいないようです。
属性でPayment Request APIの許可する、許可しないは、現状ではjavascriptで操作した方が良さそうです。そもそも、Payment Request APIの使用できる環境が整っていない。

<h2 id="canonical">canonical属性値</h2>
link要素のrel属性にcanonical属性値が追加<br>
SEOで重複するコンテンツを統合するためのcanonical属性値が正式にサポートされました。
canonical指定をしたURLを正規ページとしてインデックスするように検索エンジンに伝えることができます。<br>
URLの表記違いが発生しても、インデックスへの悪影響、SEO評価の分散は回避できます。
 
<記述方法>

```html
<link rel="canonical" href="正規ページURL">
```
<サポート状況>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941859/98c4180d-35b8-aca4-9ac1-ff166a71c807.png)
￼
対応状況はあまり良く無いが、Amazon Web Services（AWS）、Microsoft Azure、Google Cloud Platformといった主要パブリッククラウド環境で広範に活用されていることに加え、オンプレミスデータセンターや、最近ではエッジクラスター環境での利用も急成長するなど、堅調に伸びている。<br>
最近で言えば、Linuxが今年の４月に対応したバージョンをアップしました。<br>
今後、主流になる属性だと思う。

<h4>canonical属性タグを記述する場合の注意点</h4>
<h5>1.URLの記述を間違えない。人為的ミスをなくす</h5>
誤ったURLをcanonicalに記述してしまうと、その誤ったURLが正規ページとしてインデックスされ、検索結果に重大な影響がでてしまいます。<br>
特にそのURLがエラーページや404、ソフト404ページであると一切のコンテンツがインデックスされなくなってしまうばかりか、サイト全体の評価にも悪影響が出ることもあり得ます。 記述を間違えていないか入念に確認しましょう。<br>
特にページ数が膨大なウェブサイトの場合は、手動での記述は避け、できるだけCMSなどの管理ツールで自動的に記述させることが望ましいです。<br>
<h5>2.URLの記述は絶対パスを利用する</h5>
URLの記述は必ず、絶対パス（フルパス）を使用しましょう。
相対パスの記述もcanonicalのレギュレーション上は可能ですが、httpとhttpsとの区別ができないなどの問題もあり、正確な正規化には問題もあるので絶対パスを使用するようにしましょう。
<h5>3.body要素に記述しない</h5>
link rel=”canonical"はhead要素内に記述します。 body要素内に記述しても検索エンジンに処理されませんので注意してください。
<h5>4.canonical確認方法</h5>
Google Search Consoleを開きURL検査結果画面の「カバレッジ」を確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941859/da6b10ea-88ba-8ad4-e219-06051d49ccaa.png)
<h2 id="noreferrer">noreferrer属性</h2>
aリンクのreferrerを制御することが可能になり、リンクごとに設定も可能になります。 referrerとは参照元ページのURLを取得する仕組みとなっており、 例えば、"URL にユーザー名や秘密の ID などを含めざるを得ない時"などに有効です。
<p>いろいろ調べていると、以下の記事を発見しました。</p>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941859/cf711a15-cf5a-cfea-5776-4b16e5599345.png)
この記事を要約すると
・target=”_blank”属性はパフォーマンスとセキュリティ上の問題を起こしてしまう
・rel=”noopener” もしくは rel=”noreferrer”属性を付加することで対策可能
<p>では、target=”_blank”の何が問題なのか</p>
上記の記事では、二つの問題点があげれられていた
1. リンク先のページで大量のJavaScriptが走ると、呼び出し元がパフォーマンス上の影響を受ける
2. リンク先のページがwindow.opener属性を使うことで、呼び出し元ページのURLを悪意あるページに書き替えることが可能（セキュリティ上の問題）
<p>実例を作ってみたので体験してみてください。</p> 
<a href="http://kakeruwp.html.xdomain.jp/testpage/noreferrer/test.html">テストサイトはこちら</a>


<p>遷移先のページに下記のような細工をしております。</p>

```js
if (window.opener) {
opener.location='http://kakeruwp.html.xdomain.jp/testpage/noreferrer/html.html';
} 
```

<p>window.openerを使って、遷移元のサイトの操作しています。<br>今回は試しませんが、この方法を使うと別ドメインのページも閲覧者に開かせることができ、悪意ある任意にコードを実行させることが可能になってしまいます。</p>

```html
<h2>このページはnoreferrer属性の検証をするためのものです。</h2>
<a href="http://kakeruwp.html.xdomain.jp/testpage/noreferrer/" target="_blank" style="display: block; text-align: center; width: 300px; background-color: red; color: #fff; margin-top: 100px;">未対応ボタン</a>  
<p>・未対応のボタンを押した後、このページに戻ると違うページが読み込まれてしまいます。</p>
<a href="http://kakeruwp.html.xdomain.jp/testpage/noreferrer/" target="_blank" rel="noreferrer" style="display: block; text-align: center; width: 300px; background-color: blue; color: #fff; margin-top: 100px;">対応ボタン</a> 
<p>・一方noreferrer属性で対応したボタンは戻ってきても、同じこのページが表示されています。</p>
```

未対応の方は、ページに戻ると別のサイトになってしまします。
対応している方は、元のページに戻っても表示が変わりません。
このように、遷移先のサイトから、悪意ある行動を防ぐのが
rel=”noreferrer”というわけです。
<サポート状況>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941859/37bc3be0-50b0-dfea-3868-40333754ed8c.png)
対応されていないブラウザーが少し目立ちます。
対応策として、
noopener属性とセットで使うことをおすすめします。
noopener属性は、noreferrer属性の兄弟ほとんど同じ、設定になるので相違に対応していないブラウザーを補います。
特に難しい記述でも無いので、target="_blank" を使用するならrel="noreferrer"　rel="noopener"はセットで使うようにしておけば、良いと思います。

<h2 id="apple-touch-icon">apple-touch-icon</h2>
「apple-touch-icon」とは、iOS用に、ホーム画面にサイトが追加されたときに表示されるアイコンです。 iPhoneで、サイト閲覧時にメニューから「ホーム画面に追加」をしたときに表示されます。
<記述方法>

```html
<link rel="apple-touch-icon" sizes="サイズxサイズ" href="https://サイトURL/apple-touch-icon.png" />
```

のように記述してからアップします。 画像名は「apple-touch-icon.png」としておくとヘッダに記述しなくても拾ってくれるらしいのでそうしておくのが一般的のようですが、必ずしも指定しないといけないわけではないようです。
このアイコンを設置されたときに、「正しく記述して画像もアップしたのにテストしてみると反映されていない」ということがあったので対応方法について書いておきます。
まずは画像サイズによっては反映されないこともあるようなので、画像サイズは適切かどうかを確認してみてください。 （※サイズは様々なサイズで可能なようですが、私が試してみた場合では144×144で反映されました）
以下の方法を試してみると良いと思います。

 １.Safariのキャッシュを消去する
iPhoneのSafariに残っているキャッシュがクリアされていないと反映されなことがあるようです。 キャッシュの消去は「設定」→「Safari」→「履歴とWebサイトデータを消去」から消去できます。 

２.画像名を変えて、パスの記述も変えてアップしてみる
この方法でも解決することがあります。 結局、キャッシュの問題なようですが、別名にした画像ファイルをアップしてみて、パスの記述を変更すると試してみると反映されていることがあります。

今回この画像をアイコンにしてみました。
￼![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941859/d70fbadb-9071-62de-e209-e467d1e1d503.png)
￼

そして下記のようにheadタグのなかに記述しました。

```html
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="apple-touch-icon" sizes="144×144" href="http://kakeruwp.html.xdomain.jp/testpage/apple-touch-icon.png">
  <title>吉田翔</title>
</head>
```

実際にアイフォンでホーム画面に追加してみました。ちゃんと反映されていました。
￼![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941859/b4ce497d-5c40-af93-991c-6c9d24f4b6b2.png)
￼また、アンドロイド端末はapple-touch-iconを使用できるのか、調べたとこと（Android 2.3）対応し始めたみたいなので、基本的には使用可能です。
ですが、iPhoneではlinkタグで指定する以外にも、Webサーバーのルートディレクトリーに「apple-touch-icon.png（もしくはapple-touch-icon-precomposed.png）」というファイル名でアイコン画像を置く方法がありますが、Androidではこの方法には対応していません。
ですので、iPhoneとAndroidに異なるアイコンを指定する方法が良いかと思います。

```html
<link rel="apple-touch-icon" href="a.png">
<link rel="apple-touch-icon" href="b.png">
<link rel="apple-touch-icon" href="c.png">
```

さらに、「apple-touch-icon」を指定した場合は、iPhoneとAndroidどちらも同じアイコンになりますが、「apple-touch-icon-precomposed」を指定した場合は、それぞれ異なるアイコンになります。

iPhoneは、「apple-touch-icon」「apple-touch-icon-precomposed」ともに、最初に指定したアイコンが有効になるようです。一方Androidは、「apple-touch-icon」の場合は最初に指定したアイコン、「apple-touch-icon-precomposed」の場合は最後に指定したアイコンが有効になるようです。

この違いを利用して、次のような順序で記入すると、iPhoneとAndroidに異なるアイコンを指定できます。

```html
<link rel="apple-touch-icon-precomposed" href="iphone.png">
<link rel="apple-touch-icon-precomposed" href="android.png">
```

また、iPhone向けには「apple-touch-icon」を指定したい場合は、sizes属性を利用して次のように記入します（iOS 4.2以降）。

```html
<link rel="apple-touch-icon" href="android.png">
<link rel="apple-touch-icon" href="iphone.png" sizes="57x57 72x72 114x114">
```

<h2 id="douwnload">douwnload属性</h2>
douwnload属性はhtml5.2からではなくhtml5から追加された属性ですが今回とても便利だと感じたので紹介します。
ダウンロードさせるかどうか、ダウンロード時のファイル名を設定できる属性です。
使用方法は、指定した値にユーザーのデバイスのファイルシステムがファイル名に許容していない文字が含まれる場合は必要に応じてブラウザーが改変します。
<記述方法>

```html
<a href="ファイルパス" download="サンプル画像">ダウンロード</a>
```

実際にダウンロードしてみると
以下のファイルがダウンロードされます。
￼![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941859/64c3d68c-faeb-1bb7-b96e-d7dbb7764224.png)
<サポート状況>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941859/1f9275ca-f8ad-5cbe-a91d-10c19fdf67ee.png)
IEは全て対応していません。
なので、IEでのdownload属性の代替がこちらです。

```js

if(document.documentMode && navigator.msSaveOrOpenBlob){
  window.addEventListener("click", function(eve){
    var a = eve.target
    if(!a.hasAttribute("download")) return
    eve.preventDefault()
    var filename = a.getAttribute("download")
    var xhr = new XMLHttpRequest()
    xhr.open("GET", a.href)
    xhr.responseType = "blob"
    xhr.send()
    xhr.onload = function(){
      navigator.msSaveOrOpenBlob(xhr.response, filename)
    }
  })
}
```

navigator.msSaveOrOpenBlob という関数がローカルに保存する関数です。
IE と Edge にあります。
download 属性がある場合に IE ならこれを使って保存させます。
Edge では download 属性に対応してるので IE に限定するため document.documentMode も条件に入れてます。
このコードをページロード時などに実行しておけば download 属性付きリンクをクリックすると IE でもダウンロードできます。
ただし一つ注意があります。
Xhrを使う以上外部ファイルをダウンロードすることはできません。
ダウンロードさせるファイルは自分のサイトのコンテンツのことがほとんどだと思うのでそこまで問題はないかと思いますが、外部ファイルはダウンロードできません。