Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

CSP用のonclickへの対処

More than 5 years have passed since last update.

はじめに

Content-Security-Policy(CSP)に関する話です(それだけじゃないけれども)
FireFoxOSのアプリで適用されるデフォルトの認定アプリのCSP

Content-Security-Policy default-src *; script-src 'self'; object-src 'none'; style-src 'self';

ではいろいろ制限がありますがonclickが制限されます。それに対する対処法を自分用にまとめたものです。
ついでにCSPの記述方法も書いておきます(ほぼ自分用)

ここのページでどうしてこれでいいのかとかは載ってるのでそれを丁寧に、どの部分をどう分離するのかというのをまとめます

CSPの設定

いろいろなやり方はありますが、汎用性のあるmetaタグに記述します

<meta http-equiv="Content-Security-Policy" content="default-src *; script-src 'self'; object-src 'self' style-src 'self';">

http-equivにContent-Security-Policyと
contentに追加したいポリシーを記述します。

※注意
CSPは後方互換性なので間違っていると何も動きません。
スペルミスとかは注意したほうがよいです

通常のonclickの状態

<html>
<head>
</head>
<body>
<div id="box" onclick="alert('onclick')">CSPを利用しない</div>
</body>
<html>

こうするとテキストの部分をクリックするとalertが出ます。
これをonclickを使わないようにします。

CSPでonclickを別表記

event.js
var  addListener = function(elm, type, func){
    if (!elm){ return false; }
    if(elm.addEventListener) {
        elm.addEventListener(type, func, false);
    }else if(elm.attachEvent) { 
        elm.attachEvent('on'+type, func);
    }else {
        return false;
    }
    return true;
};

var init = function() {
    var div = document.getElementById('box');
    var popup = function () { alert("clicked!"); };
    addListener(div,"click",popup);
};

addListener(window,"load",init);
<html>
<head>
<script type="text/javascript" src="event.js"></script>
</head>
<body>
<div id="box">CSPを利用する</div>
</body>
</html>

タグの中で記述したevent.jsを呼び出しておき、onclick部分はCSPを利用しない場合のonclickが消えただけになります。
理論についてはこ↑こ↓を見たほうがいいです。ですが一応説明をします。

addListener部分

サイトにあるとおりここの部分は汎用的に作られてあるのでhtmlハイブリッドアプリの場合はブラウザ固定なのでここの部分は別に最初からelm.addEventListenerを呼び出してしまえば問題ないです。

動作としてはイベントリスナのAPIがあればそのイベントリスナを動かして実行させるという構成になります。
イベントリスナは引数にどんな動作が来た時,及び関数を必要とするので引数としてそれらとどの要素でイベントリスナを待つのかを引数として渡す関数となります。

init部分

init部分ではまずonclickの属性を付けたい部分を抜き出します。ここではid="box"の部分に付けたいので

var div = document.getElementById('box');

で取ります。
そのあとonclickした時に動作させたいjavascriptの関数を作ります。今回の場合はvar popupになります
最後に下記のように記述することで

addListener(div,"click",popup);

addListenerにdiv(つまりboxのところ)にclickというイベントが来た時にpopupという関数を実行するようになります

その他

最後のaddListenerはwindow(ページ)がload(読み込まれた)時にinit関数を動かす部分を記述してあるだけです。

おまけ

addListenerの部分で別にこの関数はなくても問題はないのでその表記を書きます。

CSPを適用させるのであればW3Cのブラウザになるのでまとめられますその場合は

var init = function() {
    var div = document.getElementById('box');
    var popup = function () { alert("clicked!"); };
    div.addEventListener("click",popup,false);
};

window.addEventListener("load",init,false);

となります。

最後に

今回onclickだけですが他のイベントハンドラでも多分同じように分離できると思います(試してない)
機会があればonclickなどのイベントハンドラをのっけるタグとイベントハンドラの対処のまとめでもします。
あと自分誤入力が多いです。もしなんかここちょっとおかしいんじゃね?とかあったらコメントなり編集リクエストなりいただけるとありがたいです(自分のためにも)

kataware
名工大にて情報系を学び、就職して社会人になった人間
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away