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

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

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

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

Q&A

4回答

6934閲覧

jquery ajax通信での変数データと画像データの同時送信

1ss411

総合スコア17

Ajax

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

0グッド

0クリップ

投稿2016/12/21 07:25

編集2022/01/12 10:55

ajax通信についての質問をさせていただきます。
変数データのみの送信はできるのですが、画像の送信も一緒にするとなった時にどうしても送信ができないです。

今のところ、ajax通信の中のalert文が表示されないです。

以下が実行したいプログラムです。

javascript

1var pictureSource; // 写真ソース 2var destinationType; // 戻り値のフォーマット 3 4document.addEventListener("deviceready",onDeviceReady,false); 5function onDeviceReady() { 6 pictureSource=navigator.camera.PictureSourceType; 7 destinationType=navigator.camera.DestinationType; 8} 9 10// 撮影 11function capturePhoto() { 12 // 撮影した写真をBase64形式の文字列として取得 13 navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50 }); 14} 15 16// 17function onPhotoDataSuccess(imageData) { 18 var byteString = atob(imageData); 19 var ia = new Uint8Array(byteString.length); 20 for (var i = 0, l = byteString.length; i < l; i++) { 21 ia[i] = byteString.charCodeAt(i); 22 } 23 var picBlob = new Blob([ia], 'image/jpeg'); // MIMETYPEは画像に合わせる 24} 25 26// 送信ボタンを押した後の処理 27function onButtonClick() { 28 29 var formData = new FormData(); 30 formData.append('test1', id); 31 formData.append('test2', title); 32 formData.append('test3', latitude); 33 formData.append('test4', longitude); 34 formData.append('pic', picBlob); //ここを除けば正常に動きます。 35 36 //データベースへ送信 37 $.ajax({ 38 url: "soshin.php", 39 type:"POST", 40 data: formData, 41 success: function(data){ 42 alert(data); 43 }, 44 error: function(XMLHttpRequest, textStatus, errorThrown){ 45 alert("ng"); 46 } 47 }); 48}

php

1<?php 2 3//エラー表示 4ini_set( 'display_errors', 1 ); 5 6//DB接続PHP呼び出し 7include 'MySQL.php'; 8 9//取得した画像の名前を現在のUnixタイムスタンプに置き換えるための準備 10$time = time(); 11$timerename = $time.$_POST['test2']; 12$timename = $timerename.'.jpg'; 13 14//写真の保存 15if (is_uploaded_file($_FILES['pic']['tmp_name'])) { 16 17 $tmp_path = $_FILES['pic']['tmp_name']; 18 $target_path = '/image/'.$timename; //画像保存ディレクトリ 19 20 21 //一時保存画像を保存ディレクトリに移動 22 if(move_uploaded_file($tmp_path,$target_path)){ 23 24 //保存成功 25 echo $_FILES["pic"]["name"] . "をアップロードしました。"; 26 27 } else { 28 29 //ファイルを持ってこれたが、アップロードできなかった場合 30 echo "ファイルをアップロードできません。"; 31 32 } else { 33 echo "ファイルが選択されていません。"; 34 } 35} 36 37$data1 = $_POST['test1']; 38$data2 = $_POST['test2']; 39$data3 = $_POST['test3']; 40$data4 = $_POST['test4']; 41 42//INSERT文 43$sql = $db->prepare("insert into test_1(title, latitude, longitude) 44 values(:title, :latitude, :longitude)"); 45$sql->bindParam(':title',$data2, PDO::PARAM_STR); 46$sql->bindParam(':latitude',$data3, PDO::PARAM_STR); 47$sql->bindParam(':longitude',$data4, PDO::PARAM_STR); 48$sql->execute(); 49 50$sql = 'select * from test_1;'; 51 $stmt = $db->query($sql); 52 if(!stmt){ 53 $err = $db->errorInfo(); 54 die('SELECT 失敗:' . $err[2]); 55 } 56 while($data=$stmt->fetch(PDO::FETCH_ASSOC)){ 57 print_r($data); 58 } 59 60//PDO接続終了 61unset($db); 62 63?> 64

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

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

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

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

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

guest

回答4

0

すでに@maisumakunさんがおっしゃっている部分の説明は割愛しますが、

そのほかに気づいた点として、base64のまま送信しようとしている点です。
base64はご存知かと思いますが文字列ですので、ファイルとして、つまりmultipart展開されず、単にパラメータの値として送信されると思います。
そうなると、php側で

php

1 $_FILES["pic"]

として取得することはできません。
ですので、取得したbase64の画像データをBlob型に変換してからformDataに追加し送信すれば、
ファイルとして送信することができ、$_FILES['pic']で受け取れると思います。

js

1var picBlob; 2 3navigator.camera.getPicture(onPhotoDataSucces, onFail, {quality: 50}); 4 5function onPhotoDataSuccess(imageData) { 6 var byteString = atob(); 7 var ia = new Uint8Array(byteString.length); 8 for (var i = 0, l = byteString.length; i < l; i++) { 9 ia[i] = byteString.charCodeAt(i); 10 } 11 picBlob = new Blob([ab], 'image/jpeg'); // MIMETYPEは画像に合わせる 12} 13 14function onButtonClick() { 15 var formData = new FormData(); 16 formData.add('test1', id); 17 formData.add('test2', title) 18 formData.add('test3', latitude); 19 formData.add('test4', longitude); 20 formData.add('pic', picBlob); 21 22 //データベースへ送信 23 $.ajax({ 24 url: "soshin.php", 25 type: "POST", 26 data: formData, 27 contentType: false, 28 processData: false, 29 success: function(data) { 30 alert(data); 31 }, 32 error: function(XMLHttpRequest, textStatus, errorThrown) { 33 alert("ng"); 34 } 35 }); 36}

投稿2016/12/21 08:58

編集2016/12/21 09:00
turbgraphics200

総合スコア4267

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

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

1ss411

2016/12/21 13:33

お答えいただきありがとうございます。 プログラムを動かしたところ、 formData.append('pic' , picBlob); のところがおかしいことがわかりました。 カメラ撮影後のatob()のところではないかと思っているところです。()の中には、何かの記述が必要な気がしてならないです。もし、何かわかりましたらお教えください。
turbgraphics200

2016/12/21 13:34

あ、ごめんなさい、 ```js var byteString = atob(imageData); ``` です。
1ss411

2016/12/21 14:05

早い返信ありがとうございます。 指摘していただいたところを直したのですが、変わりませんでした。 picBlobがおかしいとは思うのですが、、
turbgraphics200

2016/12/21 14:10

picBlob = new Blob([ab], 'image/jpeg'); のところ picBlob = new Blob([ia], 'image/jpeg'); 間違いでした。ごめんなさい。 あと、ChromeのdevToolsなどで送信されているデータを確認してみてはいかがでしょう。
1ss411

2016/12/21 14:29

abをiaに直しましたが、うまくいきませんでした。 それとajax通信が行われていないことが分かりました。 もし、他に気づく点があったら教えていただけるとありがたいです。
turbgraphics200

2016/12/21 14:38 編集

ごめんなさい。これ以上のことはわかりません。 ただ、ほかに気づいた点としては、私はCordova(と思う)使ったことがないからわからないのですが、 ググってみたところgetPicture()の戻り値(onPhotoDataSuccessの引数)はbase64のみの文字列を返すようですが、CordovaアップデートでDataURLスキーム("data:image/png;base64,~")で返すようになったのでしょうか。 修正前の記載されたコードに、getPicture()の戻り値をそのままimage.srcに設定してましたけど画像は表示されてるのでしょうか?
1ss411

2016/12/21 14:50

画像の表示はしています。 <img style="display:none;width:180px;height:180px;" id="smallImage" src="" /> このようにhtmlの部分に記述して表示させています。 以下はscript部分です。 var smallImage = document.getElementById('smallImage'); smallImage.style.display = 'block'; smallImage.src = imageData
turbgraphics200

2016/12/21 14:57

となると,imageDataには”data:image/png;base64,”といった文字列から始まる値が渡されいると思いますので、確認してみてください。 もし"data:~"で始まる文字列だった場合は、atob()のところは以下のように修正する必要があります。 var byteString = atob(imageData.split(',')[1]);
1ss411

2016/12/22 07:09

imageDataの値を確認しました。 file:///var/mobile/Containers/Data/Application/4A8100C4-9E3C-49E6-AE73-F6E0F474B3EC/tmp/cdr_photo_040.jpg といったものが入っていました。
turbgraphics200

2016/12/22 08:50

それは、base64ではなくファイルURIになります。 navigator.camera.getPicture()を実行するとき、qualityのみ指定して実行しているからで、optionsでdesitinationTypeを指定していなければdestinationTypeはデフォルトのCamera.DestinationType.FILE_URIで実行します。 ですので、destinationTypeも指定して実行してみてください。 navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50, destinationType: Camera.DestinationType.DATA_URL });
1ss411

2016/12/22 09:54

destinationTypeを設定して、imageDataの値を確認したところ、とても数え切れないほどの英数字の文字列が出てました。 それと、実行を試みたのですが、やはりajax通信の手前で止まってしまいます。
turbgraphics200

2016/12/22 09:59 編集

具体的にどこで止まっているのでしょうか?(どんなエラーが発生しているのか)
1ss411

2016/12/22 10:34

formData.append('pic', picBlob); の前に適当にalert("ok")を記述したら、表示はするのですが、その文の後にalert("ok")を記述したら表示されないです。
1ss411

2016/12/27 09:25

alert文は表示されるようになりました。 後は、ajax通信でエラーが返されるので、そこが分からないところです。。。
namimon

2016/12/28 00:17

エラーが返されたときは、そのエラーをこちらに書くようにしてください。
guest

0

jQuery.ajaxFormDataを送信したい場合、以下の2つの設定が必要となります(MDN)。

  • dataにはFormDataだけを指定する(他のパラメーターも全てFormDataに設定して下さい)。
  • processData: false, contentType: falseを指定する(jQuery内の処理をバイパスする必要があります)

投稿2016/12/21 07:35

maisumakun

総合スコア145062

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

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

1ss411

2016/12/21 13:36

お答えいただきありがとうございます。 上記の二点、参考にさせていただきます。
guest

0

まず、jQuery.ajax の data ですが、それに設定するのは、

(1) GET 要求(クエリ文字列としてデータを送信)の場合は JavaScript オブジェクト
(2) POST 要求(コンテンツとしてデータを送信)の場合は JSON 文字列

にする必要があるはずです。詳しくは以下の記事を見てください。質問者さんのコードでは POST で JavaScript オブジェクトを設定しているように見えます。

jQuery.ajax の data の型
http://surferonwww.info/BlogEngine/post/2015/10/05/what-must-be-set-to-data-option-in-jquery-ajax.aspx

そして、formData に設定するのを Data url 形式(画像データの文字列)とし、サーバー側ではそれを受けて元のバイト列に変換するという方法はいかがでしょう?

以下の記事の応用でできるのではないかと思います。検討ください。

canvas の画像をアップロード
http://surferonwww.info/BlogEngine/post/2015/07/02/upload-image-drawn-on-html5-canvas.aspx

Data url 形式は BASE64 でエンコードされるので、バイナリ形式よりサイズが約 1.3 倍大きくなってしまうのがなんですが。

投稿2016/12/21 08:51

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

1ss411

2016/12/21 13:35

お答えいただきありがとうございます。 monacaで行っているのですが、値の送信に関しては、javascriptでPOSTでまったく問題がなく動くので、よく分からないです。 いろいろと調べさせていただきます。
guest

0

HTMLについてでよろしいですよね?
送りたいファイルの指定方法とトリガーはどうなっていますか?

投稿2016/12/21 07:31

yambejp

総合スコア114505

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

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

1ss411

2016/12/21 13:38

今現在、turbgraphicsさんの方法を参考にさせていただいている状況です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問