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

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

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

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

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

jQuery

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

Ajax

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

HTML

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

Q&A

解決済

1回答

2590閲覧

Ajaxでテキストデータと画像データを送信したいが画像のみ送信されない

Webtuuuu

総合スコア30

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

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

jQuery

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

Ajax

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

HTML

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

0グッド

1クリップ

投稿2019/05/28 13:11

編集2019/05/28 13:25

###実現したいこと

現在簡易的なCMSを想定したジェネレータのようなものを作成しており、
ジェネレータからサーバー内に画像をアップロードする処理を作成しております。

▼基本的な動作の流れ
0. inputタグ(type="text")にURLを記載
0. inputタグ(type="file")でアップロードしたいファイルを指定(※1枚~複数枚)
0. ボタンをクリックしてAjaxからPHPにデータを送信
0. PHP側でデータを受け取る
0. 「1」で入力された階層に行きフォルダがあればそのフォルダ内に画像をアップロード
0. 「1」で入力された階層に行きフォルダがなければフォルダを作成したあとそのフォルダに画像をアップロード

###発生している問題
今回発生しているものは、基本的な動作の流れの③にあたる部分です。

送信したいデータは①のURLとなるテキストデータと、②の画像ファイルです。
この①のテキストデータはきちんとPHPに受け渡しができており、この①のデータを元に⑤と⑥のフォルダ判別ができています。

しかし、画像データを送信することができていないためフォルダは作成できても画像がアップロードできません。
###問題のコード
以下コードで実際に動かすと、PHP側から「ajaxから送信されてきたデータが空っぽだよ」が返ってきます。
※フォルダの作成もこの時点ではできていません。

しかしjs内の以下
var formdata = new FormData($('#img').get(0));
'formdata': formdata
processData: false,
contentType: false,
をコメントアウトして実行すると、フォルダの作成は実行されました。

なのでおそらくはPHP側の問題ではなくjs側の問題だとは思うのですが、原因がわからず困惑しています。

HTML

1<input type="text" name="url" id="url" > 2<input type="file" id="img" name="img" multiple="multiple" accept="image/*"> 3<div id="file_select_uploaed">アップロードボタン</div>

js

1$('#file_select_uploaed').click(function () { 2 var uploadPass = $('#url').val(); // URL文字列を取得 3 var formdata = new FormData($('#img').get(0)); // FormData オブジェクトを作成 4 5 //サーバーに送る画像と作成する階層を指定 6 var data = { 7 'imgPass': uploadPass, 8 'formdata': formdata 9 }; 10 11 $.ajax({ 12 url: 'form.php', 13 type: 'POST', 14 data: data, 15 processData: false, 16 contentType: false, 17 success: function (data) { 18 alert(data); 19 }, 20 error: function (data) { 21 alert("ajaxエラー"); 22 } 23 }); 24});

php

1<?php 2if (!empty($_POST)) { 3 4 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 ここに今回とは関係ない別の処理があります 6 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ 7 8 //==========画像フォルダの作成と画像の書き出し 9 if(!empty($_POST['imgPass'])){ 10 11 $imgPass = $_POST['imgPass']; //作成したいディレクトリ(のパス) 12 $imgData = $_FILES['formdata']['name']; //サーバーに送りたい画像の本来のファイル名 13 14 //URLをフルパスから相対パスに置換 15 $imgPass = str_replace('https://hogehoge/hugahuga/', '../../aaa/bbb/', $imgPass); 16 17 //「$imgPass」で指定されたディレクトリが存在するか確認 18 if(file_exists($imgPass)){ //ディレクトリが存在したときの処理 19 //file_existsでフォルダの中にファイルが存在しているか判定 20 if(file_exists($imgPass.$imgData)) { 21 echo '作成しようとしたファイルは既に存在します。'; // ファイルはすでにあると通知 22 } else { 23 if (move_uploaded_file($imgPass, $imgPass)) { 24 echo $imgData . "をアップロードしました。"; 25 } else { 26 echo "ファイルをアップロードできません。"; 27 } 28 } 29 30 }else{ //ディレクトリが存在しないときの処理(「$imgPass」で指定されたディレクトリを作成する) 31 if(mkdir($imgPass, 0777)){ 32 //作成したディレクトリのパーミッションを確実に変更 33 chmod($imgPass, 0777); 34 35 // file_existsでフォルダの中にファイルが存在しているか判定 36 if(file_exists($imgPass.$imgData)) { 37 echo '作成しようとしたファイルは既に存在します。'; // ファイルはすでにあると通知 38 } else { 39 if (move_uploaded_file($imgData, $imgPass)) { 40 echo $imgData . "をアップロードしました。"; 41 } else { 42 echo "ファイルをアップロードできません。"; 43 } 44 } 45 }else{ 46 //ディレクトリの作成に失敗した時の処理 47 echo "ディレクトリの作成に失敗しました"; 48 } 49 } 50 } 51} else { 52 echo 'ajaxから送信されてきたデータが空っぽだよ'; 53} 54?>

画像を送信しようとすると、PHP側から「ajaxから送信されてきたデータが空っぽだよ」が返ってくるということは
そもそもデータが空?ということになると思うのですが、
画像を送らずURLのテキストのみを送れば動くものが、なぜ画像のデータが含まれると空と判定されるのか理由がわからず…。

そもそもこのjsでは画像が取得できていないのでしょうか?

何卒宜しくお願い致します。


▼参考にしたサイト
jQuery Ajaxでファイルを送りたい!
コピペで使う!画像アップロード付きAjax(JQuery)フォームサンプル
jQueryを使ってajaxでファイル送信
PHPの入力値確認ではなぜisset関数ではなくempty関数を使うのか

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

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

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

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

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

miyabi_takatsuk

2019/05/28 14:48 編集

全然全く自信がないので、こちらで・・・。 (調査も併せてさせていただきます) なんとなくですが、送信側のAjaxの、dataType指定や、MIMETypeの指定、enctype属性など、 そこら辺の指定が足りないせいな気がします。 特に参考記事二つ目の、dataTypeが、htmlとなっているのが非常に疑問です。 画像やドキュメントファイルの送信の場合、 そのdataTypeやMIMETypeといった、 送信側のデータ型設定は重要だったりします。 (サーバーサイド側で、正しく送信してないものはデータとして認識すらしてくれない場合がある) そこあたりを、みて、再度調査いただくと、もしかしたら答えが見つかるかも。 ひとまず、こちらでも記載のソースコード使ってやってみますね。
guest

回答1

0

ベストアンサー

原因がわかりましたので、回答させていただきます。
mimetypeなどが原因ではありませんでしたすみません。

原因は、送信側の書き方で、FormDataクラスの初期化の対象となる要素が間違っているです。
現在、input要素をFormDataの引数にいれておりますが、
FormDataの引数にいれて有効になるのは、form要素です。

よって、正しくは下記になります。

html

1<!-- form要素で囲みます。actionはつけてません。(ajax送信するので) --> 2<form id="formParent" name="formParent"> 3<!-- PHP側で受け取るために、name値に、最終的に適用する引数名を入れている --> 4<input type="text" name="imgPass" id="imgPass"> 5<input type="file" id="formdata" name="formdata" multiple="multiple" accept="image/*"> 6<div id="file_select_uploaed">アップロードボタン</div> 7</form> 8 9<script> 10$('#file_select_uploaed').click(function () { 11 // FormDataの中にinputも含まれるため、下記は使わない。 12 //var uploadPass = $('#url').val(); // URL文字列を取得 13 // form要素でなければいけない。 14 var formdata = new FormData(document.forms.formParent); 15 16 17 //サーバーに送る画像と作成する階層を指定 18 // これも、form > inputの中にデータが階層づけられているので、いらない 19 /* 20 var data = { 21 'imgPass': uploadPass, 22 'formdata': formdata 23 }; 24 */ 25 26 $.ajax({ 27 url: 'form.php', 28 type: 'POST', 29 data: formdata, 30 processData: false, 31 contentType: false, 32 success: function (data) { 33 alert(data); 34 }, 35 error: function (data) { 36 alert("ajaxエラー"); 37 } 38 }); 39}); 40</script>

そもそも、FormDataクラスは、form要素(中のinputとかも全部含んだ)をJS上で扱えるようにするクラスみたいですね。

ただし、この状態で、データの送信はうまくいきましたが、アップロードはうまくいかなかったので、
この先は、php側の修正になるかと思います。

投稿2019/05/28 15:15

miyabi_takatsuk

総合スコア9528

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

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

Webtuuuu

2019/05/29 00:28

回答ありがとうございます。 上記参考にPHPの修正を試してみます。
miyabi_takatsuk

2019/05/29 01:01 編集

頑張ってください! 一応、実は、PHPの不都合も当方の環境で解決しておりますので、どうしても解決ならない時はコメントいただければと思います。 (本質問は、画像だけ送信できない、というご質問なのと、 ご自身でやった方が、エラー対応力につながると思うので、あえて回答に含めておりません)
Webtuuuu

2019/05/29 01:22

ありがとうございます!頑張ります! と言いたいところなのですが、さっそくつまづいております…。 現在PHP側の修正を試みているのですが、 PHPに関しては完全なド素人でググりながら試しています。 ただ一点初歩的な部分でつまづいており、 miyabi_takatsukさんが記載していただいたものに書き換える前の状態であれば 以下をPHP側で変数定義できたのですが、 var data = { 'imgPass': uploadPass, 'formdata': formdata }; ↓上記のデータを以下のように変数定義できた $imgPass = $_POST['imgPass']; //作成したいディレクトリ(のパス) $imgData = $_FILES['formdata']['name']; //サーバーに送りたい画像の本来のファイル名 これを var formdata = new FormData(document.forms.formParent); とした場合、 PHP側でどう変数定義したらよいのかがわからず手が止まっておりました…。 「formdata」の中から、 input(type="text")と input(type="file")をPHP側でどのように出し分けたらよいのでしょうか? (ググり方が悪いのか目ぼしいサイトを見つけられませんでした)
miyabi_takatsuk

2019/05/29 01:32

おお、なるほど、 これに関しては、 PHP側の、変数定義は変えなくて大丈夫です。 というのも、formでファイルを送る場合、 type="text"のものなどを同時に含んだformのデータであっても、 type="file"で送信したデータは、 PHP側では、$_FILES['name値']という変数に格納されるようです。 なので、PHP側の変数定義はそのままで、fileを取得できます。
Webtuuuu

2019/05/29 01:33

すいません回答が同時に重なってしまいました…! コメントいただいた内容と同様の記事でしたので試してみます!
miyabi_takatsuk

2019/05/29 01:35

いいですね、自分で調べて答えを見つけることによって、先に進みやすくなります。 エンジニアの技術力は、調査力と比例しているように最近思います。 頑張ってください〜
Webtuuuu

2019/05/29 01:58

↓以下記事を参考に修正して、無事理想とする動きになりました! https://qiita.com/yasumodev/items/cffb735f46ffd489a4db 一部記述の仕方が間違っている場所もあり諸々なおすことで達成できました。 いろいろご教示いただき大変感謝しております。 ありがとうございました。ベストアンサーとさせていただきます!
miyabi_takatsuk

2019/05/29 02:01

BAありがとうございます! 解決できてよかったですね! 実は私自身、大変に勉強になりましたので、むしろこちらこそ感謝です。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問