XMLHttpRequest Level 2 standard(まだ作業中のドラフト)はFormData
インターフェースを定義します。このインターフェースはFile
オブジェクトをXHRリクエスト(Ajaxリクエスト)に追加することを可能にします。
ところで、これは新しい機能です - 以前は "hidden-iframe-trick"が使われていました(これについては 私の他の質問 で読んでください)。
これはどのように動作するかです(例):
var xhr = new XMLHttpRequest(),
fd = new FormData();
fd.append( 'file', input.files[0] );
xhr.open( 'POST', 'http://example.com/script.php', true );
xhr.onreadystatechange = handler;
xhr.send( fd );
input
は<input type="file">
フィールドで、handler
はAjaxリクエストの成功ハンドラーです。
これはすべてのブラウザで美しく動作します(IEを除く)。
それでは、この機能をjQueryで機能させたいと思います。私はこれを試しました:
var fd = new FormData();
fd.append( 'file', input.files[0] );
$.post( 'http://example.com/script.php', fd, handler );
残念ながら、それはうまくいきません( "Illegal invocation"エラーが発生します - スクリーンショットはこちら )。私はjQueryがform-field-names/valuesを表す単純なKey-Valueオブジェクトを期待していると仮定しています、そして私が渡しているFormData
インスタンスは明らかに互換性がありません。
さて、FormData
インスタンスをxhr.send()
に渡すことが可能であるので、私はそれをjQueryで動作させることも可能であることを願っています。
更新:
私はjQueryのBug Trackerで "機能チケット"を作成しました。それはここにあります: http://bugs.jquery.com/ticket/9995
私は "Ajaxプレフィルタ"を使うように勧められました...
更新:
まず、どのような動作を実現したいのかを示すデモを見てみましょう。
HTML:
<form>
<input type="file" id="file" name="file">
<input type="submit">
</form>
JavaScript:
$( 'form' ).submit(function ( e ) {
var data, xhr;
data = new FormData();
data.append( 'file', $( '#file' )[0].files[0] );
xhr = new XMLHttpRequest();
xhr.open( 'POST', 'http://hacheck.tel.fer.hr/xml.pl', true );
xhr.onreadystatechange = function ( response ) {};
xhr.send( data );
e.preventDefault();
});
上記のコードは、このHTTPリクエストになります。
これが必要なものです - "multipart/form-data"というコンテントタイプが欲しいのですが!
提案された解決策は以下のようになります。
$( 'form' ).submit(function ( e ) {
var data;
data = new FormData();
data.append( 'file', $( '#file' )[0].files[0] );
$.ajax({
url: 'http://hacheck.tel.fer.hr/xml.pl',
data: data,
processData: false,
type: 'POST',
success: function ( data ) {
alert( data );
}
});
e.preventDefault();
});
ただし、これは次のようになります。
ご覧のとおり、コンテンツタイプが間違っています...
私はあなたがこれのようにそれをすることができると思います:
var fd = new FormData();
fd.append( 'file', input.files[0] );
$.ajax({
url: 'http://example.com/script.php',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
alert(data);
}
});
processData
をfalseに設定すると、jQueryが自動的にデータをクエリ文字列に変換するのを防ぐことができます。詳しくは ドキュメント をご覧ください。
contentType
をfalseに設定することは必須です。さもなければjQuery は間違って設定します 。
あなたが利用できるテクニックはまだいくつかあります。あなたのajaxパラメータでcontentTypeプロパティを設定することから始めましょう。
Pradeekの例に基づいて構築する:
$('form').submit(function (e) {
var data;
data = new FormData();
data.append('file', $('#file')[0].files[0]);
$.ajax({
url: 'http://hacheck.tel.fer.hr/xml.pl',
data: data,
processData: false,
type: 'POST',
// This will override the content type header,
// regardless of whether content is actually sent.
// Defaults to 'application/x-www-form-urlencoded'
contentType: 'multipart/form-data',
//Before 1.5.1 you had to do this:
beforeSend: function (x) {
if (x && x.overrideMimeType) {
x.overrideMimeType("multipart/form-data");
}
},
// Now you should be able to do this:
mimeType: 'multipart/form-data', //Property added in 1.5.1
success: function (data) {
alert(data);
}
});
e.preventDefault();
});
JQuery ajaxに予期しないことを強いる場合、beforeSend
イベントがそれを行うのに最適な場所です。しばらくの間、mimeTypeをオーバーライドするためにbeforeSend
を使用していましたが、それが1.5.1のjQueryに追加されました。送信前イベントでは、jqXHRオブジェクトのほぼすべてを変更できるはずです。
次のコードを使用して、ajaxリクエストでFormDataオブジェクトを送信できます。
$("form#formElement").submit(function(){
var formData = new FormData($(this)[0]);
});
これは一般的な回答と非常によく似ていますが、質問トピックに対する実際の回答です。これによりFormDataにフォーム要素が自動的に送信されるので、FormData変数にデータを手動で追加する必要はありません。
Ajaxメソッドはこのようになります、
$("form#formElement").submit(function(){
var formData = new FormData($(this)[0]);
//append some non-form data also
formData.append('other_data',$("#someInputData").val());
$.ajax({
type: "POST",
url: postDataUrl,
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function(data, textStatus, jqXHR) {
//process data
},
error: function(data, textStatus, jqXHR) {
//process error msg
},
});
このように、手動でFormDataオブジェクト内のフォーム要素をパラメータとして渡すこともできます。
var formElem = $("#formId");
var formdata = new FormData(form[0]);
それが役に立てば幸い。 ;)
ヘッダを操作するために$ .ajax beforeSend
イベントを使用することができます。
…
beforeSend: function(xhr) {
xhr.setRequestHeader('Content-Type', 'multipart/form-data');
}
…
追加情報については、このリンクを参照してください。 http://msdn.Microsoft.com/ja-jp/library/ms536752(v=vs.85).aspx
私はこれが好きです、そしてそれは私のために働きます、私はこれが助けになることを願っています:)
<div id="data">
<form>
<input type="file" name="userfile" id="userfile" size="20" />
<br /><br />
<input type="button" id="upload" value="upload" />
</form>
</div>
<script>
$(document).ready(function(){
$('#upload').click(function(){
console.log('upload button clicked!')
var fd = new FormData();
fd.append( 'userfile', $('#userfile')[0].files[0]);
$.ajax({
url: 'upload/do_upload',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
console.log('upload success!')
$('#data').empty();
$('#data').append(data);
}
});
});
});
</script>
JavaScript:
function submitForm() {
var data1 = new FormData($('input[name^="file"]'));
$.each($('input[name^="file"]')[0].files, function(i, file) {
data1.append(i, file);
});
$.ajax({
url: "<?php echo base_url() ?>employee/dashboard2/test2",
type: "POST",
data: data1,
enctype: 'multipart/form-data',
processData: false, // tell jQuery not to process the data
contentType: false // tell jQuery not to set contentType
}).done(function(data) {
console.log("PHP Output:");
console.log(data);
});
return false;
}
PHP:
public function upload_file() {
foreach($_FILES as $key) {
$name = time().$key['name'];
$path = 'upload/'.$name;
@move_uploaded_file($key['tmp_name'], $path);
}
}
- fd.append( 'userfile', $('#userfile')[0].files[0]);
の代わりに
使用する - fd.append( 'file', $('#userfile')[0].files[0]);
Ajaxを使用してファイルを送信したい場合は、 "jquery.form.js"を使用します。これにより、すべてのフォーム要素が簡単に送信されます。
サンプル http://jquery.malsup.com/form/#ajaxSubmit
大まかなビュー:
<form id='AddPhotoForm' method='post' action='../photo/admin_save_photo.php' enctype='multipart/form-data'>
<script type="text/javascript">
function showResponseAfterAddPhoto(responseText, statusText)
{
information= responseText;
callAjaxtolist();
$("#AddPhotoForm").resetForm();
$("#photo_msg").html('<div class="album_msg">Photo uploaded Successfully...</div>');
};
$(document).ready(function(){
$('.add_new_photo_div').live('click',function(){
var options = {success:showResponseAfterAddPhoto};
$("#AddPhotoForm").ajaxSubmit(options);
});
});
</script>