C-MOON

主にプログラミング勉強中のメモを書いていきます。

【JSON】SyntaxError: JSON.parse: expected property name or '}'…発生時の対処

以下のjsonファイルはWebブラウザでの読み込みに失敗します。

[
    { id: 1, name: "Yamada", email: "yamada@example.com" },
    { id: 2, name: "Tanaka", email: "tanaka@example.com" },
    { id: 3, name: "Suzuki", email: "suzuki@example.com" }
]

エラーメッセージです。
「構文エラーが発生しており、プロパティ名か閉じ括弧が怪しい」と言っています。

SyntaxError: JSON.parse: expected property name or '}' at line 2 column 7 of the JSON data

修正

プロパティ名はダブルクォーテーションをつける必要がありました。

[
    { "id": 1, "name": "Yamada", "email": "yamada@example.com" },
    { "id": 2, "name": "Tanaka", "email": "tanaka@example.com" },
    { "id": 3, "name": "Suzuki", "email": "suzuki@example.com" }
]

ブラウザでも、正しく表示されます。
f:id:thenewsinpu:20180621232847p:plain

おまけ

VisualStudioCodeであれば、構文エラーの発生箇所、理由が即座にわかります。
f:id:thenewsinpu:20180621233002p:plain

Angularプロジェクトでjavascriptライブラリを使用する方法

angular-cliで作成したプロジェクトで、自作のjavascriptライブラリを使用する方法です。

環境

  • angular-cli: 6.0.8
  • typescript: 2.7.2

Angularプロジェクトの作成

ngコマンドでテスト用のアプリケーションを作成します。

$ ng new my-app

Javascriptファイルの準備

例として、以下のようなjavascriptファイル「hello.js」をsrc/assrtsに作成します。
※src/assrts以外のディレクトリに配置すると動作しません。
f:id:thenewsinpu:20180615230321p:plain

function Hello() {
console.log('hello !');
}

設定ファイルの編集

angular.jsonの”scripts”にhello.jsのファイルパスを追加します。

build”: {
  (省略)
  "options": 
    (省略)
    "scripts": [
      "src/assets/hello.js"
    ]

index.htmlの編集

index.htmlでhello.jsを呼び出します。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>MyApp</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <!--  hello.js呼び出し追加 -->
  <script src="assets/hello.js"></script>

</head>
<body>
  <app-root></app-root>
</body>
</html>

ライブラリの呼び出し

app.component.tsに以下①、②を追加します。
Javascriptの関数をTypescriptで呼び出すための型定義を行い、②Hello関数を呼び出します。

import { Component } from '@angular/core';

// ① 型定義
declare function Hello(): void;
// 型定義はこれ↓でも良い
// declare var Hello: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';

  // ② hello.jsのHello()を呼び出し
  constructor() {
    Hello();
  }
}

実行結果

コンソールに「Hello !」と表示されれば成功です。 f:id:thenewsinpu:20180615233459p:plain

参考文献:

angular-cliプロジェクトにJavaScriptライブラリを組み込む方法

javascript - using external JS libraries in my angular 2 project - Stack Overflow

【ラズパイ】Raspberry PiへFirefoxをインストールする方法

コンソールを開き、以下のコマンドを入力します。

sudo apt-get update
sudo apt-get install firefox-esr



参考にしたページ: How to Install Firefox? - Raspberry Pi Forums

【Firefox】拡張機能のパッケージ化・署名・インストール

以前の記事で、Firefox拡張機能を作成し、ローカル環境でテストを行いました。

thenewsinpu.hatenablog.jp

今回は、拡張機能のパッケージ化・署名を行い、自身のブラウザにインストールしてみたいと思います。

1. パッケージ化

以下のページを参考に、拡張機能のパッケージ化を行います。

developer.mozilla.org
と言っても、パッケージ化は拡張機能に必要なファイルをすべて選択し、zip化するだけです。
今回は、以下の2ファイルです。

manifest.json
{
    "name": "KakomonDontOpacity",
    "description" : "過去問道場で解説が透明になるのを防ぎます。",
    "version": "1.0",
    "manifest_version": 2,
    "content_scripts":[
        {
        "matches":["*://www.ap-siken.com/*", "*://www.db-siken.com/*", "*://www.nw-siken.com/*"],
        "js":["kakomon_dont_opacity.js"]
        }
    ]
}
kakomon_dont_opacity.js
var ads = document.getElementsByClassName('adsbygoogle');

for (var i = 0; i < ads.length; i++){
ads[i].innerHTML = 'abc';
}


二つのファイルをzip形式で圧縮します。
f:id:thenewsinpu:20180508003108p:plain

2. 署名

拡張機能をインストール可能にするために、Mozillaによって署名を施す必要があります。
以下のページを参考にします。

developer.mozilla.org

赤枠のリンクをクリックします。
f:id:thenewsinpu:20180514230117p:plain

firefoxへのログインを求められるので、ログインします。
アカウントがない場合は新規作成します。

ログインすると、以下のページに移動します。
f:id:thenewsinpu:20180514230434p:plain
今回は投稿を行わないので、「自分自身で。」を選択し、続けるをクリックします。

次のページで、先ほど作成したzipファイルを選択します。
f:id:thenewsinpu:20180514231230p:plain

エラーや警告が無いことを確認して、「アドオンの署名」を行います。
f:id:thenewsinpu:20180517223229p:plain

アドオンの署名が完了しました。〜〜.xpiファイルが、署名されたアドオンファイルです。
「〜〜.xpiをダウンロード」ボタンでダウンロードします。
f:id:thenewsinpu:20180514231856p:plain

3. インストール

Firefoxのアドオンマネージャを開きます。
ダウンロードした〜〜.xpiファイルを下図のようにドラッグ&ドロップします。
f:id:thenewsinpu:20180514232920p:plain

拡張機能として登録されました。
f:id:thenewsinpu:20180514233315p:plain

4. 動作確認

応用情報技術者試験 過去問道場のページを開きます。
コンテンツブロッカーを使用しても、解説が非表示(半透明化)されていないことを確認します。

デバッガを使用すると、作成した拡張機能が動作しているのが確認できます。
f:id:thenewsinpu:20180517225646p:plain

今回は以上です。

【Javascript】情報技術者試験 過去問道場で解説が表示されない原因2

以前の記事で、過去問道場で解説が表示されない(半透明になる)原因を調べましたが、今月(2018年5月)に入り、解説を半透明化する条件が変更されたようです。

thenewsinpu.hatenablog.jp



条件式の比較

以前(2018年4月29日時点)のソースは以下の通りです。

if ($('.ansbg').length == 2 && Math.random() > 0.2){
    setTimeout(function(){
        var ad = $('ins.adsbygoogle')[0];
        if (ad && ad.innerHTML.replace(/\s/g , "").length === 0) {
            $('.ansbg').last().attr('style', 'opacity:.05 !important').before("<p>※解説へのアクセスはアプリやプラグインなどの拡張機能によって制限されています。</p>");
        }
    }, 2000);
}


現在のソースは以下の通りです。

if ($('.ansbg').length === 2 && Math.random() > 0.2){
    setTimeout(function(){
        var ad = $('ins.adsbygoogle').show();
        if (ad[0]) {
            ad.each(function(){
                if (!$(this).html()) {
                    $('.ansbg').last().attr('style', 'opacity:.05 !important').before("<p>※解説へのアクセスはアプリやプラグインなどの拡張機能によって制限されています。</p>");
                    return false;
                }
            });
        }
    }, 2000);
}


ins.adsbygoogleクラスの要素が広告部分で、コンテンツブロッカーを使用するとこの要素内が空になります。条件式if (!$(this).html())は要素が空かどうかを判定しています。
以前のソースはins.adsbygoogleクラスの最初の要素しかチェックしていませんでしたが、現在のソースではすべてのins.adsbygoogleクラスの要素をチェックしています。

半透明化を防ぐ拡張機能の改良

前回の記事で作成した拡張機能は、「適当な文字を入れたinsタグでadsbygoogleクラスの要素」をbodyタグ先頭に追加する処理を行っていましたが、上記の通り、すべてのins.adsbygoogleクラスの要素の文字数をチェックされてしまうため、半透明化を防げなくなりました。

現在の半透明化条件式に対応するため、拡張機能のソースを改良します。

参考までに、改良前のソースです(ファイル名:kakomon_dont_opacity.js)。

var insertText = '<ins class="adsbygoogle">abc</ins>';
document.body.insertAdjacentHTML('afterbegin', insertText);



このソースを以下のように変更します。

var ads = document.getElementsByClassName('adsbygoogle');

for (var i = 0; i < ads.length; i++){
    ads[i].innerHTML = 'abc';
}

改良後のソースは、ページ内すべてのins.adsbygoogleクラスの要素に適当な文字列*1を挿入します。
これにより、空のins.adsbygoogleクラスの要素は無くなるので、半透明化処理は行われないはずです。

拡張機能の動作確認

Firefoxのデバッガーを使用し、半透明化の条件式に入らないこと、解説がきちんと表示されることを確認しました。
f:id:thenewsinpu:20180516233057p:plain

今回は以上です。

*1:コンテンツブロッカーを使用していれば、ins.adsbygoogleクラスの要素は非表示になるので、文字列がページに表示されることはありません。

情報技術者試験 過去問道場で解説が半透明になるのを防ぐ拡張機能

前回、 応用情報技術者過去問道場|応用情報技術者試験.com で解説が半透明になり見えにくくなる問題の原因を調査しました。

thenewsinpu.hatenablog.jp



今回は、解説が透明になるのを防ぐブラウザ拡張機能(アドオン)を開発してみます。

開発は、Firefoxで行います。

拡張機能の開発は以下のページを参考に行います。

developer.mozilla.org

1. ディレクトリの作成

任意の場所に任意の名前のディレクトリを作成します。

今回は、デスクトップに「KakomonDontOpacity」という名前のディレクトリを作成しました。

2. manifest.jsonを作成

作成したディレクトリ「KakomonDontOpacity」内に「manifest.json」ファイルを作成し、以下のように記述します。

{
    "name": "KakomonDontOpacity",
    "description" : "過去問道場で解説が透明になるのを防ぎます。",
    "version": "1.0",
    "manifest_version": 2,
    "content_scripts":[
        {
        "matches":["*://www.ap-siken.com/*", "*://www.db-siken.com/*", "*://www.nw-siken.com/*"],
        "js":["kakomon_dont_opacity.js"]
        }
    ]
}


"content_scripts"配列内の"matches"では、対象となるURLを選択できます。
今回は、「応用情報技術者試験.com」「データベーススペシャリスト.com」「ネットワークスペシャリスト.com」を指定しました。

3. kakomon_dont_opacity.jsの作成

ディレクトリ「KakomonDontOpacity」内に「kakomon_dont_opacity.js」ファイルを作成し、以下のように記述します。

var insertText = '<ins class="adsbygoogle">abc</ins>';
document.body.insertAdjacentHTML('afterbegin', insertText);


前回の記事で調査した通り、情報技術者試験 過去問道場ではinsタグでadsbygoogleクラスの1つ目の要素の文字数が0のとき解説を半透明にする処理を行っていました。

「適当な文字を入れたinsタグでadsbygoogleクラスの要素」をbodyタグ先頭に追加すれば、上記条件に引っかからなくなります。

【2018/05/16 追記】
過去問道場の半透明化処理の条件式が変更されていました。
上記処理では半透明化を防げません。
以下のソースに変更してください。
詳細はこちら

var ads = document.getElementsByClassName('adsbygoogle');

for (var i = 0; i < ads.length; i++){
    ads[i].innerHTML = 'abc';
}

4. インストール

"about:debugging" を Firefox で開いたら "一時的なアドオンを読み込む" をクリックし、アドオンのディレクトリにあるファイルをどれか 1 つ選択します。

5. テスト

μBlock等のコンテンツブロッカーを有効にします。
次に、応用情報技術者過去問道場|応用情報技術者試験.com にアクセスし、解説を表示させます。
解説が透明になっていなければ、成功です。
f:id:thenewsinpu:20180507005323p:plain

今回は以上です。

【Javascript】情報技術者試験 過去問道場で解説が表示されない原因

応用情報技術者試験の勉強で応用情報技術者過去問道場|応用情報技術者試験.comを利用していますが、問題を解いた後、解説が表示されない(厳密にはうっすら見えてる)状態になります。
f:id:thenewsinpu:20180428224423p:plain

原因

ページに「※解説へのアクセスはアプリやプラグインなどの拡張機能によって制限されています。」と書かれているので解るのですが、一応ヘルプページを見ます。

過去問道場の使い方・各機能について|応用情報技術者試験.comによると、

過去問道場(PC版、スマホ版)では、広告ブロックのプラグイン等を使用している場合に解説部分が広告と一緒に非表示になる仕組みを取り入れているため、それが影響している可能性があります。

広告をブロックすると解説を表示させない仕組みのようです。

確かに、私はコンテンツブロッカー「μBlock Origin」を使用していおり、サイトをホワイトリストに追加することで解説が表示されました。

コンテンツブロッカー使用で解説が非表示になる仕組み

応用情報技術者」を目指すものとしては、コンテンツブロッカー使用で解説が非表示になる仕組みがどのようなっているのか気になるので、調べることにしました。

サイトのJavascriptを確認

解説を消し、「※解説へのアクセスはアプリやプラグインなどの拡張機能によって制限されています。」という一文を表示させる処理を行っているのはサーバ(PHP等)でしょうか?ブラウザ(Javascript)でしょうか?

コンテンツブロックはブラウザ側の処理なので、解説を消す/消さないの判断もブラウザ(Javascript)で行う必要があるはずです。

さっそく、サイトのソースを表示し、Javascriptを確認します。
私の環境がFirefoxなので、Firefoxで説明します。
ブラウザでF12を押し、開発ツールを表示します。
f:id:thenewsinpu:20180428233123p:plain
デバッガーのタブを選び、Ctrl(⌘)+Shift+F で「解説へのアクセス」を検索します。すると、以下のように、該当箇所がヒットします。
f:id:thenewsinpu:20180428233942p:plain なぜか二つ表示されますが、両方同じです。

該当箇所を抜粋しました。

if ($('.ansbg').length == 2 && Math.random() > 0.2){
    setTimeout(function(){
        var ad = $('ins.adsbygoogle')[0];
        if (ad && ad.innerHTML.replace(/\s/g , "").length === 0) {
            $('.ansbg').last().attr('style', 'opacity:.05 !important').before("<p>※解説へのアクセスはアプリやプラグインなどの拡張機能によって制限されています。</p>");
        }
    }, 2000);
}

HTMLを確認すると、ansbgは問題文と解説タグのクラスで、広告はinsタグadsbygoogleクラスの要素です。
抜粋したソースの上から4行目を見ると、'ins.adsbygoogle'要素の子要素の文字数が0の場合、解説を消す処理を行っています。(不透明度0.5に設定)

確かに、広告をブロックすると、'ins.adsbygoogle'要素の子要素がなくなります。
子要素が無い(文字数が0)ことを検知して、解説を消していたわけです。

・コンテンツブロック無し f:id:thenewsinpu:20180428235700p:plain
・コンテンツブロック有り f:id:thenewsinpu:20180428235724p:plain

【2018/05/16 追記】
過去問道場の半透明化処理の条件式が変更されていました。
詳細は以下ページを参照してください。
thenewsinpu.hatenablog.jp 【追記 ここまで】

まとめ

情報技術者試験 過去問道場で解説が表示されない原因(解説を消す処理の仕組み)を知ることができました。
もし、コンテンツブロッカーを使用したまま解説を表示させたいと考えた時、仕組みがわかれば方法を思いつくことができます。
例えば、解説を消す処理は、ifで複数の条件を満たす必要があります。
この条件に必ず当てはまらなくなるようにすれば、解説が消されることはありません。

今回は以上です。