Help us understand the problem. What is going on with this article?

headに<base target="_blank">1行入れるだけで、全リンクのデフォルトを_blank化できた

外部リンクはtarget='_blank'にする事多いと思います。でも一々設定する作業って、すごい大変で時間がかかりますよね。

javascriptで、a_tags.setAttribute('target','blank')という命令/例外処理をしたりなどという方法を使わずに、たった1行をheadに書けば、全てのリンクのデフォルトがtarget='blank'になる方法をご紹介します。そのたった1行とは、これです。

<base target="_blank">

全てのリンクのデフォルトを、1行だけでtarget='_blank'にする方法

まずは、headタグの中に、この1行を追加しましょう。

<head>
  ......
  <base target="_blank">
  ......
</head>

このbaseタグ、初めて見る方も多いのではないでしょうか?

baseタグを使えば、基準ターゲットだけでなく基準URLも設定できる

baseタグとは、head内に記述すると
①基準URLを指定できる
②基準ターゲットを指定できる
という2つの機能を果たします。

①の機能に関しては、ご存知の方もいるのではないでしょか?
よく他のサイトのHTMLを除くと、こんな相対href設定を見たことがあると思います。

<a href="category/0001">XXX</a>

この相対href設定を行う際に、head内にこのようなbaseタグを配置する必要があるのです。

<head>
  <title>ほげほげ</title>
  <base href="http://www.hogehoge/">
</head>

こうする事で、ソースコード削減やサイトマップ効率化を図る事ができるんですね。

しかし、今回の②基準ターゲットを指定できるについては初めて知った方も多いと思います。

基準ターゲットの設定できる4種類

baseタグで設定可能な基準ターゲットは、下記の4種類です。

  • _self ⇛ 同タブに表示します
  • _blank ⇛ 別タブに表示します
  • _parent ⇛ 分割ウィンドウの親フレームに表示
  • _top ⇛ 分割ウィンドウを全解除して表示

皆さんが普段一般的に利用する基準ターゲットはやはり、「_blank」ですよね。
ですので、今回ご紹介した

<head>
  ......
  <base target="_blank">
  ......
</head>

という記述だけを貼れば大丈夫です。
一部のリンクはselfにしたいという時は、これまで通り、そのリンクのaタグ内にtarget='self'と記述してください。

デフォルトをtarget='_blank'にする際の注意点

実は、target='_blank'にはセキュリティ脆弱性が存在します。
簡単に言うと仕様上、下記のリスクなどが発生してしまうのです。
①_blank先のサイトで重いスクリプトが駆動すると元サイトのリソースも食ってパフォーマンスが落ちる
②親ウィンドウのオブジェクトにアクセスされてしまう

Google公式のソース

このリスクを回避するために、全ての_blankのタグにrel="noopener"を追加する必要があるのですが、
そもそも安全が保証されている自サイトリンクに対しては、処理を重くしたくないので追加したくありませんよね?

ですので、下記に別サイトに対するリンクに対してだけrel="noopener"を追加するスクリプトを用意致しました。
(5/18追記 @ahya_emon 様作成 )

const add_noopener_to_external_link = () => {
    Array.from(document.getElementsByTagName("a"))
        .filter((a) => a.host !== window.location.host) // サイト内遷移ははじく
        .forEach((a) => a.setAttribute('rel', 'noopener'))
}
document.addEventListener('DOMContentLoaded', add_noopener_to_external_link, false);

旧スクリプト 非推奨
//var external_link__add_blank = function(){
//    var a_tags = document.querySelectorAll('a');
//    res = [];
//    if(!a_tags.length) return;
//    for(var i = 0; i < a_tags.length; i++ ){
//      if( a_tags[i].href.indexOf(window.location.host) !== -1 ) continue;
//      if( a_tags[i].href.indexOf('#') === 1 ) continue;
//      a_tags[i].setAttribute('rel','noopener');
//      res.push(a_tags[i])
//    }
//    return res;
//}
//document.addEventListener('DOMContentLoaded',external_link__add_blank,false);

これをbodyタグ終了直前に貼って頂ければ、全ての他サイトに対するtarget='_blank'のaタグに、
セキュリティリスクをなくすrel="noopener"が自動的に付与されます。

baseタグを使って、サイト運営作業の時間を大幅に短縮しよう!

今回ご紹介した方法を利用して頂くと、

  • 今まで全部手作業で追加していたtarget='_blank'が自動付与される
  • target='_blank'のセキュリティリスクが自動的に対策される

という、時間的にもリスク的にも大きな恩恵をうける事ができます。

参照サイト

Baseタグの説明
http://www.tohoho-web.com/html/base.htm

今回の記事制作のきっかけとなった、皆大好きColiss様の記事。
https://coliss.com/articles/build-websites/operation/work/target-blank-in-base-element.html

ryuta69
ᓚᘏᗢ zzz...。oO
https://github.com/ryuta69
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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした