質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

1回答

1285閲覧

URLチェックについて

jjj001

総合スコア55

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2021/09/13 11:12

編集2021/09/13 11:38

javascriptでURLをチェックする関数を作成したのですが、URLの形式ではないものがチェックを通過してしまっている状況です。
以下のような形でcheck_url関数に対して、http://gdnoalgadaなどの文字列を検査してもtrueとなってしまいif文内の条件式の中が実行されませんでした

if (!check_url('http://gdnoalgada')){ console.log('hogehoge') } check_url(url) { let re = /https?://[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#\u3000-\u30FE\u4E00-\u9FA0\uFF01-\uFFE3]+/g; return re.test(url); },

こちらの問題を解消する方法につきまして、ご助言頂けましたら幸いです

追記
URLの定義としましては、WEBサイトのアドレスを想定し、「.com」や「.jp」,「.net」などのトップレベルドメインがついているものに限定したいと考えています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jjj001

2021/09/13 18:49 編集

> http://192.168.1.1 そうですね... URLの打ち込みでIPアドレスを直打ち込みする人は少ないと思うので、今回の仕様からははずそうと思っています
guest

回答1

0

new URL

new URL を利用して検証。

JavaScript

1'use strict'; 2function sample1 (string) { 3 const url = new URL(string); 4 5 switch (url.protocol) { 6 case 'https:': 7 case 'http:': 8 const hostname = url.hostname; 9 const i = hostname.indexOf('.'); 10 return i !== -1 && i !== 0 && i !== hostname.length - 1; 11 } 12 13 return false; 14} 15 16console.assert(sample1('http://localhost') === false); 17console.assert(sample1('https://.foo') === false); 18console.assert(sample1('https://bar.') === false); 19console.assert(sample1('http://example.com') === true); 20console.assert(sample1('https://baz.example') === true); 21console.assert(sample1('ftp://example.com') === false);

<input type="url">

<input type="url"> を利用して検証。

JavaScript

1'use strict'; 2const sample2 = ((baseInput)=>{ 3 return function sample2 (string) { 4 const input = baseInput.cloneNode(false); 5 input.value = string; 6 7 return input.validity.valid; 8 }; 9})((()=>{ 10 const input = document.createElement('input'); 11 12 input.type = 'url'; 13 input.pattern = 'https?://[^#?/.]+\..+'; 14 15 return input; 16})()); 17 18console.assert(sample2('http://localhost') === false); 19console.assert(sample2('https://.foo') === false); 20console.assert(sample2('https://bar.') === false); 21console.assert(sample2('http://example.com') === true); 22console.assert(sample2('https://baz.example') === true); 23console.assert(sample2('ftp://example.com') === false);

正規表現

正規表現でも実装できますが、非常に複雑化する為、お勧めしません。
簡略化を試みる場合は妥協が必要になります。

HTML

1<script src="./rfc3986.js"></script> 2<script> 3'use strict'; 4function sample3 (string) { 5 const rfc3986 = new RFC3986; 6 7 return new RFC3986().isAbsoluteURI(string) && /https?://[^#?/.]+..+/.test(string); 8} 9 10console.assert(sample3('http://localhost') === false); 11console.assert(sample3('https://.foo') === false); 12console.assert(sample3('https://bar.') === false); 13console.assert(sample3('http://example.com') === true); 14console.assert(sample3('https://baz.example') === true); 15console.assert(sample3('ftp://example.com') === false); 16</script>

Re: jjj001 さん

投稿2021/09/13 12:05

編集2021/09/15 14:41
think49

総合スコア18189

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jjj001

2021/09/13 19:49 編集

ご丁寧、ご親切にご回答頂きありがとうございます。 せっかくご回答くださったのに、今更ながら申し上げるのは本当に、申し訳ないのですが実は「http://」はついておらずとも、簡単にユーザーにURLを入力させる為、ページスピードインサイトhttps://developers.google.com/speed/pagespeed/insights/ のような形でドメインのみで判定できるようにしたいと考えておりました。 その為、think49さんに頂いた回答を元に以下のように作成してみました const inputUrl = 'http://test.com' const test = isHttpUrlWithDomain(inputUrl) console.log(test) function isHttpUrlWithDomain (string) { let re = /^http(|s)://.+/; let isProtocol = re.test(string); if(isProtocol){ console.log(string) const url = new URL(string); return url.hostname.includes('.'); }else{ console.log(string) checkUrl = 'http://' + string const url = new URL(checkUrl); return url.hostname.includes('.'); } } こちら、一点問題があるのですが、仮に「inputUrl 」の値が「test.」であった場合、ドットと記入されている為、「test」の値は「true」となってしまいます。 こちら細かくやればきりがないかもしれないのですが、ここまでは気にする程ではありませんでしょうかね...?
think49

2021/09/15 14:47 編集

「https://.foo」と「https://bar.」をNGにする事は <input type="url"> と「正規表現」のコードでは実装できていました。 new URLのコードでも同様に扱うには、indexOfで "." の位置を検出すれば良いでしょう(修正済)。 > http://」はついておらずとも、簡単にユーザーにURLを入力させる index.html が http://index.html になるので、TLDをホワイトリストで指定するなりしないと誤検出する気はします。
jjj001

2021/09/17 00:08

ありがとうございます! > index.html が http://index.html になるので、TLDをホワイトリストで指定するなりしないと誤検出する気はします。 こちらそうですね。index.htmlとなってしまう点は、関数が複雑になってしまうような気がしていて、どうするか要検討かなと思っています... 自分は、修正頂いた「new URL」を使った形、プラスドメインのみで検索(httpをつけず検索可能)できる方法で実装できたらと考えているのですが、正規表現だとコード量的には少ないので、どちらにするか迷う所ですね... ただ正規表現のコードとinpu type=urlを用いたコードはほとんど分かっていないので、それを実装するのもどうなのかなというのはあります...
jjj001

2021/09/17 01:13 編集

一旦は、new URLの形で実装してみて、「http://index.html 」こちらのような形は一旦許容する形で実装し、ホワイトリストを作成するかどうかは後々検討していきたいと思います
jjj001

2021/09/17 02:35 編集

new urlのロジックで少々気になったのですが、「 i !== hostname.length - 1 」こちらでは何に対するチェックを行っているのでしょうか...?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問