見出し画像

何が原因?新人エンジニアの困った事例3選

こんにちは、D2C ID沖縄オフィスでエンジニアをしている川満です。
エンジニアとして働き始めて、たくさんの案件に関わってきた中で、何が原因なのか…どう解決したら良いのか…と頭を抱えたことが何度もありました。今回は特に困った事例3つと、その解決方法をご紹介します。


事例1:リダイレクト先にURLパラメータが引き継がれない


「/hogehoge.html?firstParam=aaaaaaa.html?secondParam=bbb」というURLから
「aaaaaaa.html?secondParam=bbb」と遷移するはずが、
「aaaaaaa.html?secondParam」と遷移してしまう。
アナリティクスで確認しても、パラメータが確認できない。

こちらはディレクターさんとアナリストさんからの相談でした。熟練エンジニアの方はこの時点で原因を察したかもしれませんが、当時の私は初めて受けた相談だったためひとつずつ原因をさぐっていきました。

■事前に
・URLパラメータとは?
サーバーに情報を送るためにURLに付け加える変数のこと。 具体的には、URLの末尾につけられている「?」以降の文字列です。複数付ける場合には、パラメータ同士を「&」でつなぐ必要があります。
パラメータに名前をつける場合、
「【パラメータ名】=【パラメータの値】」と記述します。

・エンコード、デコードについて
エンコードとは、手元にあるデータを変化させる方法のことです。似たような処理として「デコード」がありますが、こちらは逆に、エンコードしたデータを元の形式に戻すことになります。
今回の話では、URLのパラメータを扱うので以下のような意味になります。
エンコード:テキスト(日本語、英数字、記号など)をHTMLエンティティ(&で始まり、;で終わる文字列)に変換すること。
デコード:HTMLエンティティ(&で始まり、;で終わる文字列)をテキスト(日本語、英数字、記号など)に変換すること。

■何が原因だったのか?
原因となったのは以下の2点でした。
【原因1】リダイレクトの際に行っていた処理で想定外の挙動が起こった
【原因2】パラメータとして付与されていた値がエンコードされていなかった

順に説明していきたいと思います。

【原因1】リダイレクトの際に行っていた処理で想定外の挙動が起こった
このサイトのリダイレクト処理はJavaScriptによって行われています。その時の記述が以下になります。

// ①パラメータ(「?」以降)を取得
 var refURL = location.search;
// ②「&」で分割、配列として持つ
var paramList = refURL.split("&");
// 分割したパラメータの配列をある分だけ、順々に処理を行っていく
for(var i = 0; i < paramList.length; i++){
// もしパラメータの中に「firstParam」という文字列が含まれていたら
  if(paramList[i].indexOf("firstParam") > -1){
    // ③パラメータを「=」で分割、パラメータの値の方を取得する
    var paramValue = paramList[i].split("=")[1];	// 問題の箇所!
    // ④取得したパラメータの値を、デコードする
    var decodeParam = decodeURIComponent(paramValue);
    break;
  } 
}
// ⑤リダイレクトを行う
location.href = decodeParam;

詳しい処理の内容はコード内にコメントで記述していますので省きますが、取得したパラメータの値をURLとして遷移を行う比較的シンプルなコードです。
コード内③の行に”問題の箇所!”というコメントがありますが、こちらが想定外の挙動を起こしたコードです。

コード内③がどのような挙動を起こしていたのか見ていきたいと思います。
まずは「paramList[ i ]」の中身はこちら。

firstParam=aaaaaaa.html?secondParam=bbb

そしてこの「paramList[ i ]」の中身を「=」で分割した中身がこちら。

[ 0 ]firstParam
[ 1 ]aaaaaaa.html?secondParam
[ 2 ]bbb

 [ 1 ]を取得していますので、「paramValue」に入る値はこちらです。

aaaaaaa.html?secondParam

本当に欲しい値は以下でした。

aaaaaaa.html?secondParam=bbb

「=」で分割した際、「bbb」の前にある「=」でも分割が入ってしまったことが原因で、「bbb」は含まれないままになってしまったのです。

【原因2】パラメータとして付与されていた値がエンコードされていなかった
ではなぜ、「=」で分割されてしまったのでしょうか?
2つ目の「=」がパラメータに含まれていることがそもそも想定されていないコードだったからです。

ブラウザは基本的に半角英数字や一部の半角記号しか扱えません。使用できない文字を含めたい場合には安全な文字に変換する必要があります。その変換作業のことをURLエンコードやパーセントエンコーディングと呼びます。
(参照:https://e-words.jp/w/%E3%82%AF%E3%82%A8%E3%83%AA%E6%96%87%E5%AD%97%E5%88%97.html
JavaScriptの制作者としても上記のようなエンコードが行われていることが前提だったのではないでしょうか。

■解決方法
直接的な原因はJavaScriptの記述でしたが、【原因2】で分かる通りパラメータを以下のようにエンコード化しておくことで防ぐことができる事例でした。

/hogehoge.html?firstParam%3Daaaaaaa.html%3FsecondParam%3Dbbb

パラメータ値に日本語が含まれていなくてもエンコードを行っておくと、今回のような想定外の挙動を減らせるかもしれません。

事例2:LINEのアプリ内ブラウザで起こった挙動


ブラウザから画像や動画のダウンロードをさせたいという話がありました。Chrome、Safari、Firefoxなど主流のブラウザでの挙動確認は特に問題なく済んだのですが、唯一ダウンロードができないブラウザがありました。それがLINEのアプリ内ブラウザです。

■何が原因だったのか?
初めて知ったのですが、こちらはLINEの内部ブラウザの標準挙動でした。どうやらLINEの内部ブラウザはファイルダウンロードに対応していないらしいです。(2024/04/25時点)

■解決方法
今回の事例では、「別ブラウザで開いてもらう」という方法を使うことにしました。
遷移するURLに以下のパラメータを付与して、それぞれのスマートフォンのデフォルトブラウザでサイトを閲覧してもらう方法です。

&openExternalBrowser=1

※どのブラウザで開くかは各スマートフォンの設定によります。

事例3:Xへのシェアで更新したOG画像が反映されない

とあるサイトを更新したところ、一部ページのOG画像が更新されないという事態が起こりました。画像のパスも間違っていない、もちろん画像もちゃんとサーバーに上がっています。それなのに、XにシェアをしたときだけOG画像が更新されず前の状態のまま…。

■事前に
OG画像とは、Facebook、Instagram、LINE、XなどSNSでページが共有されたときに表示される画像のことです。OGPとも呼ばれます。

■何が原因だったのか?
もともとOG画像があり、同じファイル名の画像を上書きする形で更新したため、キャッシュが残ってしまっていたのが原因でした。調べてみたら解決方法の記された記事がたくさん出てきたので、かつてからある事象のようですね…。

■解決方法
そのままではしばらく更新が確認できないのですが、以下のページで一度プレビューの確認をしたところ、OG画像の更新が確認できました。
https://cards-dev.twitter.com/validator/

今回はすぐに更新が確認できたのですが、どうやらすぐに反映されない可能性もあるようです。場合によっては7日待つことになる可能性もあるとか。
参考URL:https://qiita.com/takepan/items/af77efdabed436f5de10
別ファイルとして更新してしまう方が安心かもしれませんね…。

最後に

エンジニア1年目の頃よりいろいろな知識を得たことで、昔はできなかったことができるようになったと思いますが、まだまだ知らないことがたくさんあります。これからもエンジニアとして精進し、さらに他の方にもわかりやすく説明できるように知識を深めていこうと思います。

D2C ID沖縄オフィスでは、一緒に働くメンバーを募集しています。
興味のある方はぜひエントリーしてみてください!みなさんの応募をお待ちしています。


この記事が気に入ったらサポートをしてみませんか?