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

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

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

Cygwinは、Unixのような環境を、Windows上で構築させるコマンドラインインターフェースです。

JavaScript

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

Ajax

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

3回答

18319閲覧

POSTでリクエストできGETでリクエストできない

takato

総合スコア148

Cygwin

Cygwinは、Unixのような環境を、Windows上で構築させるコマンドラインインターフェースです。

JavaScript

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

Ajax

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2016/01/15 06:44

編集2016/01/21 03:28

失礼します。
以前POST、GETどちらかを選択してリクエストを送れる方法を教えていただきました。
POSTでリクエストは問題なくできるのですがGETでリクエストをかけた場合400エラーがコンソールで確認できました。
chromeだけでなくfirefoxなど違うブラウザでも同じようなエラーが生じました。
cygwin上で同じようなリクエストする場合はGETかPOSTを書き換えるだけでリクエストができていたのですが。。。
もしくはHTML上だとGETでリクエストできないのでしょうか?

追記:Developer Toolsで確認したところ下記の「Request Method:GET」の文字の間に赤丸のエラーが出ていました。

xml

1Request URL:http://52.192.178.185:8280/api/dept_accesses?{%22dept_ids%22:[%22BD0004%22],%22start_date%22:%2220151001%22,%22end_date%22:%2220161207%22} 2Request Method:GET 3Status Code:400 Bad Request 4Remote Address:52.192.178.185:8280

HTML

1<body> 2<html> 3 <td><b>URL: <input type="text" id="url_post" name="url" size="100" value="http://52.192.178.185:8280/api/dept_accesses"></b><td> 4 </tr><td> </td> 5 <td><b>店舗ID:<textarea cols="50" id="dept_ids" pattern="^[0-9A-Za-z]+$" class="keyword"></textarea></td> 6 </tr> 7 <tr><td><b>開始日: <input type="text" id="start_date" size="30" value="20151001" class="keyword"> 8 ~ 終了日: <input type="text" id="end_date" size="30" value="20161207" class="keyword"> 9 <select id="method_select"> 10<option value="GET" selected>GET</option> 11<option value="POST">POST</option> 12</select> 13<button type="submit" value="送信"> 14</button> 15 <button id="button" type="button">検索結果</button></p></td> 16 <td><textarea id="response" cols=170 rows=21 disabled></textarea></td> 17</body> 18</html>

javascript

1$.ajax({ 2 url : url, 3 type : ("#method_select").val(), 4 data : JSON.stringify(JSONdata), 5 contentType: "application/json;charset=UTF-8", 6 processData: false, 7 dataType : "json", 8 accepts : {json: "application/vnd.glv.v1+json;charset=UTF-8"}, 9 crossDomain: false 10}).done(function(data, status, xhr) { 11 $("#response").html(JSON.stringify(data)); 12}).fail(function(xhr, status, error) { 13 // 通信失敗時の処理 14 alert("失敗"); 15}).always(function(arg1, status, arg2) { 16 // 通信完了時の処理 17 alert("完了"); 18 });

1/18追記2 以下はGET、POSTでフォーム選択できるソースです。

HTML

1<form action="http://52.192.178.185:8280/api/rankings" id="FORM" Accept-charset="UTF-8"> 2<b>ランキング種別</b><font color="RED">:必須</font><br> 3<p>【車種別:0】【メーカー別:1】【ボディタイプ別:2】【メーカー別:3】【国産車別:4】【輸入車別:5】</p> 4<p><input type="text" value="0" name="kind" placeholder="例:0" pattern="^[0-9]+$" class="keyword"></p> 5 6~~略~~ 7 8<b>リクエスト方法</b><br> 9<select id="method_select"> 10<option value="GET" selected>GET</option> 11<option value="POST">POST</option> 12</select> 13<button type="submit" class="btn btn-default btn-sm dropdown-toggle"> 14<span class="glyphicon glyphicon-search" aria-hidden="true"></span> 15</button> 16

javascript

1 $(function() { 2 $('#FORM').on('submit', function(e) { 3 e.preventDefault(); 4 var $form = $(this).clone(); 5 $form.prop('method', $('#method_select').val()); 6 $(this).find(':input').each(function() { 7 var $element = $(this); 8 if ($element.val() == '') { 9 $form.find('*[name="' + $element.prop('name') + '"]').remove(); 10 } 11 }); 12 $form.submit(); 13 }); 14 });

1/21追記

eripong様からWiresharkというアプリを使いどんなデータが送られている調べることができました。
その結果POST時とGET時のリクエストパラメーターが一緒のため片方にエラーが生じてしまうといった原因が判明しました。
ですので今後の処理としてリクエストパラメーター自体を変更しないといけないので本スレッドを閉め今回判明した問題を他トピックで質問させていただきます。

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

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

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

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

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

eripong

2016/01/15 11:20

ChromeのDeveloper Toolsでは、ネットワークタブでXHRの応答が見えると思うのですが、何かエラーメッセージは出ていませんか?
takato

2016/01/18 01:05

eripong様 いつもありがとうございます。コンソールで確認したところ違うところもエラーが出ていました。内容は文章に追記しました。
guest

回答3

0

ベストアンサー

Request URL:http://52.192.178.185:8280/api/dept_accesses?{%22dept_ids%22:[%22BD0004%22],%22start_date%22:%2220151001%22,%22end_date%22:%2220161207%22}

とあるように、Request URLにjsonが付加されてしまっています。
これはリクエストボディに含まれるべきデータです。
そのため、400 Bad Requestになってしまっていると考えられます。

jQueryではGETはリクエストボディ無しとしている様なので、
jQueryを使って、takatoさんの実現したいことはできなそうです。

xhrを直接使えば実現はできるのではないかと思いますが、
そもそも、なぜGETでjsonリクエストしたいのでしょうか?

jQueryでGETリクエストはボディ無しとしていることの根拠

jQueryのリファレンスのdataパラメータの説明を見ると、

Data to be sent to the server. It is converted to a query string, if not already a string. It's appended to the url for GET-request

とありdataの内容をurlに付加すると記述されています。

また、jQueryのソースを見ると、以下の様に、GETとHEADの場合にはhasContentがfalseになる様に判定しています。

lang

1rnoContent = /^(?:GET|HEAD)$/,p

lang

1 // Determine if request has content 2 s.hasContent = !rnoContent.test( s.type ); 3 4 // Save the URL in case we're toying with the If-Modified-Since 5 // and/or If-None-Match header later on 6 // Remove hash to simplify url manipulation 7 cacheURL = s.url.replace( rhash, "" ); 8 9 // More options handling for requests with no content 10 if ( !s.hasContent ) { 11 12 // Remember the hash so we can put it back 13 uncached = s.url.slice( cacheURL.length );

投稿2016/01/18 03:18

編集2016/01/18 03:34
eripong

総合スコア1546

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

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

takato

2016/01/18 03:29

epipong様 できないのですか・・・ 他のやり方で模索中でしたがうまくいかないです。 細かく話すとWEBアプリ作成中でしたのでcygwin上で確認後、今度はローカル内でHTMLを使用して実際にリクエストできるかどうか試そうと思いました。 cygwin上ではリクエストする際のフォーム指定はGETかPOST書き換えるだけだったので簡単にできると思いました。特に深い意味はないです。
eripong

2016/01/18 03:41 編集

jQueryでGETリクエストはボディ無しとしていることの根拠を追記しました。 cygwinから、というのはどういうコマンドでしょうか? 推測ですが、そのコマンドではPOSTでもGETでもリクエストボディに データを載せることができるのではないかと思います。 あまり深い意味が無いのであれば、jQueryではできない、 というレベルでやめておいても良いのかなと思います。
eripong

2016/01/18 03:48

それから、HTTPの仕様としては、GETにリクエストボディを含めることは 許容されているようですが(含めてはいけないという記述を、ざっと見た限りでは 見つけられませんでした)、一般的にはあまりやらないように思います。
takato

2016/01/18 05:15

eripong様 表題とまったく同じリクエストをかける場合だと下記です。 curl -i -v -H "Accept: application/vnd.glv.v1+json" -H "Content-type: application/json" -X POST localhost:8280/api/dept_accesses -d '{"dept_ids":["BD0004"],"start_dat"20151001","end_date":"20151207"}' jqueryを使用し画面遷移してしまいますがGET、POST両方ともリクエストに成功しているソースがありますがそれと今回は全く別物なのでしょうか?
eripong

2016/01/18 05:22

GETの場合はcurlの引数のPOSTをGETにするだけ、ということで良いでしょうか? そうであれば、リクエストボディにパラメータが載るので動くと思います。 jQueryを使用しPOST、GET両方とも成功する場合のソースでも、 application/jsonでデータを送っていますか?
takato

2016/01/18 05:43

eripong様 左様でございます。仕様が異なるので同じようにHTML上ではできないということですよね? はい。似たようなソースなので質問の項目に追記します
eripong

2016/01/18 06:11

追記していただいたソースでは、contentTypeを指定しておらず、 普通のformでの送信なので、うまくいきそうです。 POSTの時はリクエストボディに、 GETの時はリクエストボディは無しで、クエリストリングにパラメータが付加されて 送信されます。
eripong

2016/01/18 06:49

> 仕様が異なるので同じようにHTML上ではできないということですよね? 仕様が異なるというのが、どんな仕様がどの様に異なるかを書いていただかないと、 ちょっと分かりません。
takato

2016/01/18 07:18

eripong様 親身にコメントありがとうございます。 でしたら後に記述したソースをベースにAJAXを使用して画面遷移しないようにするほうが手っ取り早いでしょうか?できるかはわかりませんが… cygwin上だとリクエストする際パラメーターが若干違うため仕様が異なるのではないかと推測し書かせていただきました。勘違いもしくは知識不足でしたら申し訳ありません。
eripong

2016/01/18 07:25

サーバ側での処理次第です。 application/jsonのリクエストだけでなく、 通常のformによるパラメータ送信にも対応していれば、 それも可能です。 サーバはどの様なリクエストを受け付けていますか? Toyoshimaさんがapiのキーといっているのも、同じような意味と思います。
takato

2016/01/18 07:45

eripong様 確認しようとtcpdumpをcygwinで叩いてみましたがコマンドが見つからないと表示されました。他の調べ方をご存知でしたら教えていただけないでしょうか?
eripong

2016/01/18 08:27 編集

パケットキャプチャするにはサーバが別マシンでなければなりませんが そこは大丈夫でしょうか?
takato

2016/01/18 08:36 編集

eripong様 インストールさせてただきます。 パケットキャプチャを使用したことがないので今調べておきます。
eripong

2016/01/18 08:29

別マシンの誤りです。失礼しました。 サーバもクライアントと同じマシンなのですか?
takato

2016/01/18 08:40

揚げ足を取るような形になってしまい申し訳ありません。 恐らく別マシンなので問題ないかと思います。
eripong

2016/01/18 08:41

いえ、誤変換のままも嫌なので、指摘していただいて良かったです。
takato

2016/01/18 09:00

eripong様 質問に長く付きあっていただき感謝しております。 ダウンロードの途中ですが。。。
guest

0

ajax送信の各パラメタは、期待どおりでしょうか?
上手くいかない場合は、パラメタの値をブラウザのデバッガや、alertなどで事前に確認してみたほうがよいです。

こういう場合は、リクエスト先のWEBサーバにもログが出ていると思いますので、そちらも併せて確認するなどして、原因を追究していきます。

次はソース拝見して気づいたベースですが・・・

type : ("#method").val(),

の部分ですが・・・・"method"をidに持つHTML要素が無いように見受けられます。
もしかしたら、

type : ("#method_select").val(),

が正しいのでは・・・?

投稿2016/01/18 02:06

Toyoshima

総合スコア422

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

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

Toyoshima

2016/01/18 04:12 編集

GETでJSONデータの文字列をパラメタで送って処理することは可能です。 実現はできますので、ご安心を。。 リクエストパラメタの形式に、キーがないですね。。 例えば、キーをhoge としたら http://52.192.178.185:8280/api/dept_accesses?hoge={・・・JSONデータ・・・} のようにしなければならないです。 ※jQueryでajaxする場合、dataパラメタは、連想配列を設定するのではなかったでしたっけ。。 パラメタのキーは、apiの仕様で決められているので、apiのプログラムを見ればわかるはずです。 http://52.192.178.185:8280/api/dept_accesses の処理を見てみると、きっと リクエストパラメタが無い場合は 400 を返すような処理になってたりしませんか? あと、送るべきデータに、「:」など入っちゃってます。これは、http://とかで使う想定のキャラクタなので、エスケープが必要です。 その他も"/"や"?"や”=”・・・・など、URLとして意味を持つキャラクタはエスケープが必要なのですが、その作業はencodeURI 関数でできるはずです。
Toyoshima

2016/01/18 04:10

こうなるのかな?・・・検証してませんけども・・・。 var request = Array(); //この"hoge"は、APIの仕様に従ったパラメタ名にしてください request["hoge"] = encodeURI(JSON.stringify(JSONdata)); $.ajax({ url : url, type : ("#method_select").val(), data : request, contentType: "application/json;charset=UTF-8", processData: false, dataType : "json", accepts : {json: "application/vnd.glv.v1+json;charset=UTF-8"}, crossDomain: false }).done(function(data, status, xhr) { $("#response").html(JSON.stringify(data)); }).fail(function(xhr, status, error) { // 通信失敗時の処理 alert("失敗"); }).always(function(arg1, status, arg2) { // 通信完了時の処理 alert("完了"); });
eripong

2016/01/18 04:28

その場合、 processData : true にしなければならないのでは無いでしょうか?
Toyoshima

2016/01/18 05:03

>eripongさん なるほど。。。その必要がありそうですね。。
takato

2016/01/18 06:33

Toyoshima様 お手数おかけしました。早速試させていただいたところ「Uncaught TypeError: "#method_select".val is not a function」のエラーが出ました。。。 パラメーターのキーの仕様についてわからなかったので返答が来る前に調べておきます!
eripong

2016/01/18 06:52

> takatoさん ("#method_select").val() でなく、 $("#method_select").val()だと思います。
takato

2016/01/18 07:06

eripong様 細かな点からご指摘ありがとうございます。 書き直した際に省いてしまいました。
guest

0

今、送信しようとしているのはJSON形式のパラメータなのですよね?
そうであれば下記が原因では?

(2) パラメータを JSON形式で送信する場合

Content-Type に application/json を指定して下さい。 指定しない場合は JSON が解釈できないため、実行時エラーとなります。

投稿2016/01/15 11:05

pi-chan

総合スコア5936

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

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

eripong

2016/01/15 11:14

contentType: "application/json;charset=UTF-8", とあるので、Content-Typeにapplication/jsonを指定することはできているのでは?
pi-chan

2016/01/15 11:38

すみません、スマホ版で見ていたので見落としてしまいました。。。無視してください。
eripong

2016/01/15 11:49

了解です。 スマホで見たことないですが、細かいところは見落としそうですね。
takato

2016/01/18 01:21

pi-chan様 初めましてスマートフォンからでもご親切にアドバイス頂き感謝しております。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問