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

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

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

HttpWebRequestとは.NETにおけるクラスであり、WebRequestクラスをHTTPに導入するものです。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

0回答

903閲覧

固有(独自)の関数を素のJavaScriptに置き換えたい。@grant GM_xmlhttpRequest

Meli_ssa

総合スコア0

HttpWebRequest

HttpWebRequestとは.NETにおけるクラスであり、WebRequestクラスをHTTPに導入するものです。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

1クリップ

投稿2022/10/01 13:36

編集2022/11/04 07:48

前提、実現したいこと

私は現在、特にFirefoxで選択したテキストをポップアップ状で(日本語に)翻訳するスクリプトを使用しています。
いちいちwindow.openで翻訳サイトに飛ばされる工数をショートカットできるという事実に、たいへん意義と価値を感じて気に入って使っています。

しかし、GM_xmlhttpRequest({ 何らかの通信処理 });という形式にはめなければならず、現状ではTampermonkey系でしか使えない状態です。
ネットで調べた情報によれば、この特有の関数は new XMLHttpRequest();のような役割を担っているとの事だったのでnew XMLHttpRequest();に置き換えて、Tampermonkey系からの依存度を減らしたい(例えばブックマークレットとかからも実行できるようにしたい...etc)と考えています。

しかし、試してみてもnull「接続失敗」という結果しか返ってきません。

この事に関してお詳しい方、ご教示お願いできればと思います。

該当のソースコード

Tampermonkey

JavaScript

1// ==UserScript== 2// @name textを選択して任意の言語を日本語に翻訳 3// @version 1.3.5 4// @description ←最も不要だと思うが、これ設定しないと叱られる 5// @match *://*/* 6// @run-at document-start 7// @connect translate.google.com 8// @grant GM_xmlhttpRequest 9// ==/UserScript== 10 11//「// @connect」は、某サイトの機能をユーザーが使うか確認するストッパー(安全装置)を取り外すような役割があり、なくても煩わしいだけで使える。 12// また、「// @connect」自体はTampermonkeyの設定「セキュリティ」→「@connect 文を確認: 」→「無効」に調整可能。 13 14window.addEventListener('load', () => { 15 16'use strict'; 17var target_language = 'auto'; // 翻訳targetは、的を絞らず多言語に対応したいので auto 18// 以下は元のURLから &tl=ja を語尾にくっつけただけ。↓ 19var googleUrl = 'https://translate.google.com/translate_a/single?client=gtx&dt=t&dt=bd&dj=1&source=input&hl=auto&sl=auto&tl=ja'; 20var iconSize = 24; 21var translationTestSize = 16; 22var icon = document.createElement('div'); 23var word = ''; 24var style = '' + 25'width:23px;' + 26'height:23px;' + 27'margin:4px!important;' + 28'cursor: pointer;' + 29''; 30 31icon.innerHTML = // <svg><path> がダラダラ長過ぎるので <img> に変更 32'<img src="https://storage.googleapis.com/gweb-uniblog-publish-prod/images/Translate_logo.max-500x500.png" style="width:23px; height:23px; margin-top:5px;margin-left:5px; cursor: pointer; ">'; 33 34icon.setAttribute('style', '' + 35'width:32px!important;' + 36'height:32px!important;' + 37'display:none!important;' + 38'background:#fff!important;' + 39'border-radius:16px!important;' + 40'box-shadow:4px 4px 8px #888!important;' + 41'position:absolute!important;' + 42'z-index:2147483647!important;' + 43''); 44// DOM に翻訳アイコンを追加する 45document.documentElement.appendChild(icon); 46 47 48 // マウス イベント: 選択したテキストが消えるのを防ぐ 49 document.addEventListener('mousedown', (e) => { 50 // // 翻訳アイコンをクリック 51 if (e.target == icon || (e.target.parentNode && e.target.parentNode == icon) || (e.target.parentNode.parentNode && e.target.parentNode.parentNode == icon)) { 52 e.preventDefault(); 53 } 54 }); 55 56 57 // 選択変更イベント: 選択したテキストをクリックすると、翻訳アイコンと翻訳パネルが非表示に。 58 document.addEventListener("selectionchange", () => { 59 if (!window.getSelection().toString().trim()) { 60 icon.style.display = 'none'; 61 server.containerDestroy(); 62 } 63 }); 64 65 66 // マウス イベント: 選択したテキストが消えるのを防ぐ; 翻訳アイコンを表示、非表示に。 67 document.addEventListener('mouseup', (e) => { 68 // // 翻訳アイコンをクリック 69 if (e.target == icon || (e.target.parentNode && e.target.parentNode == icon) || (e.target.parentNode.parentNode && e.target.parentNode.parentNode == icon)) { 70 e.preventDefault(); 71 return; 72 } 73 for (var i = 0; i < server.rendered.length; i++) { // 翻訳コンテンツ パネルをクリック 74 if (e.target == server.rendered[i]) 75 return; // 翻訳アイコンを作成しない 76 } 77 var text = window.getSelection().toString().trim(); 78 word = text; 79 if (text && icon.style.display == 'none') { 80 icon.style.top = e.pageY + 12 + 'px'; 81 icon.style.left = e.pageX + 'px'; 82 icon.style.display = 'block'; 83 } else if (!text) { 84 icon.style.display = 'none'; 85 server.containerDestroy(); // 翻訳コンテンツ パネルを破棄 86 } 87 }); 88 89 90 // 翻訳アイコンクリックイベント 91 icon.addEventListener('click', (e) => { 92 var text = window.getSelection().toString().trim(); 93 if (text) { 94 icon.style.display = 'none'; 95 server.containerDestroy(); // 翻訳コンテンツ パネルを破棄 96 // 新しい翻訳コンテンツ パネルを作成。 97 var container = server.container(); 98 container.style.top = e.pageY + 'px'; 99 if (e.pageX + 350 <= document.body.clientWidth) //コンテナ パネルの最大幅 250px。 100 container.style.left = e.pageX + 'px'; 101 else 102 container.style.left = document.body.clientWidth - 350 + 'px'; 103 document.body.appendChild(container); 104 server.rendered.push(container); 105 googleUrl += `&tk=${token(text)}`; 106 if (isJapan_customized_by_me(text)) { 107 // 英語に対して日本語変換処理? 108 ajax(googleUrl + '&tl=en&q=', encodeURIComponent(text), 1, container); 109 // ajax(googleUrl + '&tl=ja&q=', encodeURIComponent(text), 1, container); 110 } else if (countOfWord(text) !== 1) { 111 // 多言語に対して日本語変換処理? 112 ajax(googleUrl + '&tl=' + target_language + '&dt=t&q=', encodeURIComponent(text), 1, container); 113 } 114 } 115 }); 116 117 118 function countOfWord(str) { 119 var value = String(str); 120 value = value.replace(/^\s+|\s+$/gi, ""); // 先頭と末尾のスペースは単語としてカウントされない 121 value = value.replace(/\s+/gi, " "); // 複数のスペースを 1 つのスペースに置き換え 122 var length = 0; //更新回数 123 var match = value.match(/\s/g); // 一致しない場合 null を返す 124 if (match) { 125 length = match.length + 1; 126 } else if (value) { 127 length = 1; 128 } 129 return length; 130 } 131 132 133 function isJapan_customized_by_me(str) { 134 var reg = /^([\u4E00-\u9FA5]|[\uFF00-\uFF20]|[\u3000-\u301C])+$/; 135 return !!reg.test(str); 136 } 137 138 139 // Google 翻訳のトークン計算 140 function token(a) { 141 const b = 406644; 142 const b1 = 3293161072; 143 const jd = "."; 144 const sb = "+-a^+6"; 145 const Zb = "+-3^+b+-f"; 146 let e = []; 147 let f = 0; 148 let g = 0; 149 for (e = [], f = 0, g = 0; g < a.length; g++) { 150 let m = a.charCodeAt(g); 151 128 > m ? e[f++] = m : (2048 > m ? e[f++] = m >> 6 | 192 : (55296 == (m & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (m = 65536 + ((m & 1023) << 10) + (a.charCodeAt(++g) & 1023), e[f++] = m >> 18 | 240, e[f++] = m >> 12 & 63 | 128) : e[f++] = m >> 12 | 224, e[f++] = m >> 6 & 63 | 128), e[f++] = m & 63 | 128) 152 } 153 a = b; 154 for (f = 0; f < e.length; f++) a += e[f], 155 a = RL(a, sb); 156 a = RL(a, Zb); 157 a ^= b1 || 0; 158 0 > a && (a = (a & 2147483647) + 2147483648); 159 a %= 1E6; 160 return a.toString() + jd + (a ^ b); 161 } 162 163 164 // Google 翻訳のトークン計算、token() 165 function RL(a, b) { 166 const t = "a"; 167 const Yb = "+"; 168 for (let c = 0; c < b.length - 2; c += 3) { 169 let d = b.charAt(c + 2); 170 d = d >= t ? d.charCodeAt(0) - 87 : Number(d); 171 d = b.charAt(c + 1) == Yb ? a >>> d : a << d; 172 a = b.charAt(c) == Yb ? a + d & 4294967295 : a ^ d; 173 } 174 return a; 175 } 176 177 178 // ajax はドメイン全体でパブリック メソッドにアクセス 179 function ajax(url, text, target, element, method, data, headers) { 180 181 if (!!!method) 182 method = 'GET'; 183 184 url += text; 185 if (!!!headers) 186 headers = { 187 'cookie': '' 188 }; 189 190 //--------------------------------------------------------// 191 // 試した事 ↓ 192 193 /* 194 var xhr = new XMLHttpRequest(); 195 xhr.onload = function (res) { 196 if(target !== 0){ 197 google(res.responseText, element); 198 } 199 } 200 xhr.open(method, url,[headers, data], false); // true 201 xhr.send(); 202 xhr.onerror=function(res){ 203 displaycontainer("接続失敗",element); 204 } 205 xhr.send(null); 206 */ 207 208 //--↓ 以下から Tampermonkey依存の関数 ↓ -----------------// 209 210 GM_xmlhttpRequest({ 211 method: method, 212 url: url, 213 headers: headers, 214 data: data, 215 onload: function(res) { 216 if (target !== 0) { // target == 0 改め 217 // 省略 }else{ 218 google(res.responseText, element); 219 } 220 }, 221 onerror: function(res) { 222 displaycontainer("接続失敗", element); 223 } 224 }); 225 226 //↑ 以上までがTampermonkey依存の関数 ↑ ---------------// 227 228 } 229 230 231 // この辺りの内容を大幅省略 232 233 234 // Google 翻訳エンジン 235 function google(rst, element) { 236 var json = JSON.parse(rst), 237 html = ''; 238 for (var i = 0; i < json.sentences.length; i++) { 239 html += json.sentences[i].trans; 240 } 241 displaycontainer(html, element); 242 store_ajax(word, html, element); 243 } 244 245 246 function displaycontainer(text, element) { 247 element.innerHTML = text; 248 element.style.display = 'block'; // 結果を表示 249 } 250 251 252 // 翻訳サーバー 253 var server = { 254 // 生成された翻訳コンテンツパネルを格納(破棄時に使用) 255 rendered: [], 256 // 生成された翻訳コンテンツ パネルを破棄する 257 containerDestroy: function() { 258 for (var i = this.rendered.length - 1; i >= 0; i--) { 259 if (this.rendered[i] && this.rendered[i].parentNode) { 260 this.rendered[i].parentNode.removeChild(this.rendered[i]); 261 } 262 } 263 }, 264 265// 翻訳結果パネル DOM を生成 (この時点ではまだページに追加されていない) 266container: function() { 267var div = document.createElement('div'); 268div.setAttribute('style', '' + 269'display:none!important;' + 270'position:absolute!important;' + 271'font-size:13px!important;' + 272'overflow:auto!important;' + 273'background:#fff!important;' + 274'font-family:sans-serif,Arial!important;' + 275'font-weight:normal!important;' + 276'text-align:left!important;' + 277'color:#000!important;' + 278'padding:0.5em 1em!important;' + 279'line-height:1.5em!important;' + 280'border-radius:5px!important;' + 281'border:1px solid #ccc!important;' + 282'box-shadow:4px 4px 8px #888!important;' + 283'max-width:350px!important;' + 284'max-height:216px!important;' + 285'z-index:2147483647!important;' + 286''); 287return div; 288} 289}; // 翻訳サーバーの終了 290 291}); 292

補足

追記ですが
Greasemonkeyとの互換性はありません。
Violentmonkeyとの互換性はあります。

ホームを追記します
https://www.tampermonkey.net/documentation.php#GM_xmlhttpRequest

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問