ユーザーからのファイル入力を実際に使用せずに、ファイルのアップロードを偽造しようとしています。ファイルのコンテンツは、文字列から動的に生成されます。
これは可能ですか?これまでにこれをやったことがありますか?例/理論はありますか?
明確にするために、私はAJAX非表示のiframeと友人を使用したテクニックを使用してファイルをアップロードする方法を知っています-問題はフォームにないファイルをアップロードすることです。
私はExtJSを使用していますが、ExtJSがプラグイン(ext-jquery-base)に接続できるため、jQueryも実行可能です。
POSTでXMLHttpRequest()
を使用しないのはなぜですか?
function beginQuoteFileUnquoteUpload(data)
{
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://www.mysite.com/myuploadhandler.php", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function ()
{
if (xhr.readyState == 4 && xhr.status == 200)
alert("File uploaded!");
}
xhr.send("filedata="+encodeURIComponent(data));
}
サーバーのハンドラスクリプトは、ファイルデータをファイルに書き込むだけです。
[〜#〜] edit [〜#〜]
ファイルのアップロードは、異なるコンテンツタイプのhttp投稿のままです。このコンテンツタイプを使用して、コンテンツを境界で区切ることができます。
function beginQuoteFileUnquoteUpload(data)
{
// Define a boundary, I stole this from IE but you can use any string AFAIK
var boundary = "---------------------------7da24f2e50046";
var xhr = new XMLHttpRequest();
var body = '--' + boundary + '\r\n'
// Parameter name is "file" and local filename is "temp.txt"
+ 'Content-Disposition: form-data; name="file";'
+ 'filename="temp.txt"\r\n'
// Add the file's mime-type
+ 'Content-type: plain/text\r\n\r\n'
+ data + '\r\n'
+ boundary + '--';
xhr.open("POST", "http://www.mysite.com/myuploadhandler.php", true);
xhr.setRequestHeader(
"Content-type", "multipart/form-data; boundary="+boundary
);
xhr.onreadystatechange = function ()
{
if (xhr.readyState == 4 && xhr.status == 200)
alert("File uploaded!");
}
xhr.send(body);
}
追加のデータを送信する場合は、各セクションを境界で区切って、各セクションのcontent-dispositionヘッダーとcontent-typeヘッダーを記述するだけです。各ヘッダーは改行で区切られ、本文は追加の改行でヘッダーから区切られます。当然、この方法でバイナリデータをアップロードするのは少し難しくなります:-)
さらなる編集:言及するのを忘れて、送信するテキスト「ファイル」にない境界文字列を確認してください。そうでない場合は、境界として扱われます。
古いブラウザのサポートが必要ない場合は、File APIの一部であるFormDataオブジェクトを使用できます。
var formData = new FormData();
var blob = new Blob(['Lorem ipsum'], { type: 'plain/text' });
formData.append('file', blob,'readme.txt');
var request = new XMLHttpRequest();
request.open('POST', 'http://example.org/upload');
request.send(formData);
File Apiは現在のすべてのブラウザー(IE10 +)でサポートされています
機能する最終結果を共有するだけで、ハードコーディングすることなくパラメーターを追加/削除することができます。
var boundary = '-----------------------------' +
Math.floor(Math.random() * Math.pow(10, 8));
/* Parameters go here */
var params = {
file: {
type: 'text/plain',
filename: Path.utils.basename(currentTab.id),
content: GET_CONTENT() /* File content goes here */
},
action: 'upload',
overwrite: 'true',
destination: '/'
};
var content = [];
for(var i in params) {
content.Push('--' + boundary);
var mimeHeader = 'Content-Disposition: form-data; name="'+i+'"; ';
if(params[i].filename)
mimeHeader += 'filename="'+ params[i].filename +'";';
content.Push(mimeHeader);
if(params[i].type)
content.Push('Content-Type: ' + params[i].type);
content.Push('');
content.Push(params[i].content || params[i]);
};
/* Use your favorite toolkit here */
/* it should still work if you can control headers and POST raw data */
Ext.Ajax.request({
method: 'POST',
url: 'www.example.com/upload.php',
jsonData: content.join('\r\n'),
headers: {
'Content-Type': 'multipart/form-data; boundary=' + boundary,
'Content-Length': content.length
}
});
これは、以下を含むがこれらに限定されない最新のすべてのブラウザーで動作するようにテストされました。
ファイルのアップロードは、そのファイルコンテンツが適切にエンコードされ、特別なmultipart/formdata
ヘッダーを持つPOST
リクエストにすぎません。ブラウザのセキュリティにより、ユーザーディスクに直接アクセスすることは禁止されているため、その<input type=file />
を使用する必要があります。
ユーザーディスクを読み取る必要がないため、[〜#〜] yes [〜#〜]、Javascriptを使用して偽造できます。それはXMLHttpRequest
になります。 「本物の」アップロードリクエストを偽造するには、 Fiddler
をインストールし、送信リクエストを検査します。
そのファイルを正しくエンコードする必要があるため、このリンクは非常に便利です。 RFC 2388:フォームからの戻り値:multipart/form-data
Firefox TamperDataアドオンでこのPOST_DATA文字列をキャッチしました。 1つのtype="file"
「myfile」という名前のフィールドと、「btn-submit」という名前の「Upload」という値の送信ボタン。アップロードされたファイルの内容は
Line One
Line Two
Line Three
これがPOST_DATA文字列です。
-----------------------------192642264827446\r\n
Content-Disposition: form-data; \n
name="myfile"; filename="local-file-name.txt"\r\n
Content-Type: text/plain\r\n
\r\n
Line \n
One\r\n
Line Two\r\n
Line Three\r\n
\r\n
-----------------------------192642264827446\n
\r\n
Content-Disposition: form-data; name="btn-submit"\r\n
\r\n
Upload\n
\r\n
-----------------------------192642264827446--\r\n
数字の意味はわかりません(192642264827446)が、それほど難しくはないはずです。
JQueryで「偽の」ファイルアップロードを模倣する簡単な方法:
var fd = new FormData();
var file = new Blob(['file contents'], {type: 'plain/text'});
fd.append('formFieldName', file, 'fileName.txt');
$.ajax({
url: 'http://example.com/yourAddress',
method: 'post',
data: fd,
processData: false, //this...
contentType: false //and this is for formData type
});
https://stackoverflow.com/a/2198524/2914587 余分な'--'
ペイロードの最後のboundary
の前:
var body = '--' + boundary + '\r\n'
// Parameter name is "file" and local filename is "temp.txt"
+ 'Content-Disposition: form-data; name="file";'
+ 'filename="temp.txt"\r\n'
// Add the file's mime-type
+ 'Content-type: plain/text\r\n\r\n'
+ data + '\r\n'
+ '--' + boundary + '--';