私は解決策があるかもしれないと思います。以下は私が使用したいフォームです:
<!--removing the action ensures form will be sent via javascript, then when that request comes back, I can add in the authenticated youtube URL needed-->
<form id="upload" action="" method="POST" enctype="multipart/form-data" class="form-horizontal"><!--upload.php-->
<fieldset>
<legend><h1>Video File Upload</h1></legend>
<input type="hidden" id="MAX_FILE_SIZE" name="MAX_FILE_SIZE" value="1000000000" /> <!--1GB-->
<p id="filedrag">Drag and drop a video file from your computer here. Or use the 'File upload' button below.</p><!--dragFileHere-->
<label class="control-label" for="fileselect">Files to upload:</label>
<input type="file" id="fileselect" name="fileselect[]" /> <!--multiple="multiple"-->
<button class="btn" id="submitbutton" type="submit">Upload Files</button> <!--hidden via js/css-->
<div class="progress progress-striped active">
<div class="bar" style="width: 0%;"></div>
</div>
<label class="hide" for="video-title">Title</label>
<input type="text" id="video-title" class="span4" placeholder="Video Title"/>
<label class="control-label" for="video-category">Category</label>
<select id="video-category" name="videoCategory" class="span4">
<option value="Autos">Autos & Vehicles</option>
<option value="Music">Music</option>
.......
<option value="Entertainment" selected>Entertainment</option>
</select>
<input id="token" type="text" placeholder="token"/> <!--will be hidden-->
</div>
</fieldset>
</form>
action属性を空白のままにすることで(そして、ユーザーの操作に応答するためにすでに配置されているスクリプトを使用して)、フォームがjavascriptを介してプログラムで送信されるようにすることができます。
<script src=http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js></script>
<script src=_js/video_app.js" type="text/javascript></script>
<script>
/*
filedrag.js - HTML5 File Drag & Drop demonstration
Featured on SitePoint.com
Developed by Craig Buckler (@craigbuckler) of OptimalWorks.net (without jQuery)
*/
// output information
function Output(msg) {
$('#messages').html(msg + $('#messages').html());
}
// file drag hover
function FileDragHover(e) {
e.stopPropagation();
e.preventDefault();
$(this).addClass("hover");
}
function FileDragOut(e) {
$(this).removeClass("hover");
}
// file selection
function FileSelectHandler(e) {
// cancel event and hover styling
FileDragHover(e);
// fetch FileList object
var files = e.target.files || e.dataTransfer.files;
// process all File objects
for (var i = 0, f; f = files[i]; i++) {
ParseFile(f); //prints file data to div and optionally displays content of selected file
UploadFile(f); //uploads file to server
}
}
// output file information
function ParseFile(file) {
videoName = file.name;
videoType = file.type;
videoURL = "http://localhost/"+videoName;
videoCategory = $('#video-category').val();
Output(
"</strong> type: <strong>" + file.type +
"</strong> size: <strong>" + file.size +
"</strong> bytes</p>"
);
// sets a default value because a title is needed for youtube to send response
if( $('#video-title').val() == $('#video-title').attr('placeholder') ) {
$('#video-title').val(videoName);
}
var reader = new FileReader();
reader.onload = function(e) {
var fileContents = e.target.result;
Output(
'<img src="'+e.target.result+'"/>'
);
}
reader.readAsDataURL(file);
//get upload token
ytVideoApp.prepareSyndicatedUpload(videoName, videoCategory);
}
// upload video files
function UploadFile(file) {
var xhr = new XMLHttpRequest();
if (xhr.upload && file.size <= $('#MAX_FILE_SIZE').val()) { //&& file.type == "video/mp4" or video/*
xhr.upload.addEventListener("progress", function(e) {
var pc = Math.ceil(e.loaded / e.total * 100);
}, false);
// file received/failed
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4) {
if(xhr.status == 200) { //success
} else { //fail
}
}
};
// start upload
xhr.open("POST", 'upload.php', true); //$("#upload").attr('action')
xhr.setRequestHeader("X_FILENAME", file.name);
xhr.send(file);
}
}
// initialize
function Init() {
// file select
$('#fileselect').change(FileSelectHandler);
// is XHR2 available?
var xhr = new XMLHttpRequest();
if (xhr.upload) {
// file drop
$('#filedrag').bind('dragover', FileDragHover);
$('#filedrag').bind('dragleave', FileDragOut);
//I can't get the below line to work, so I've used the ugly fallback
//$('#filedrag').bind('drop', FileSelectHandler);
document.getElementById('filedrag').addEventListener("drop", FileSelectHandler, false);
filedrag.style.display = "block";
// remove submit button
submitbutton.style.display = "none";
}
}
// call initialization file
if (window.File && window.FileList && window.FileReader) {
Init();
}
</script>
_js / video_app.js:
/**
* Zend Framework
* @package Zend_Gdata
....
/**
* provides namespacing for the YouTube Video Application PHP version (ytVideoApp)
**/
var ytVideoApp = {};
/**
* Sends an AJAX request to the server to retrieve a list of videos or
* the video player/metadata. Sends the request to the specified filePath
* on the same host, passing the specified params, and filling the specified
* resultDivName with the resutls upon success.
* @param {String} filePath The path to which the request should be sent
* @param {String} params The URL encoded POST params
* @param {String} resultDivName The name of the DIV used to hold the results
*/
ytVideoApp.sendRequest = function(filePath, params, resultDivName) {
if (window.XMLHttpRequest) {
var xmlhr = new XMLHttpRequest();
} else {
var xmlhr = new ActiveXObject('MSXML2.XMLHTTP.3.0');
}
xmlhr.open('POST', filePath);
xmlhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhr.onreadystatechange = function() {
var resultDiv = document.getElementById(resultDivName);
if (xmlhr.readyState == 1) {
resultDiv.innerHTML = '<b>Loading...</b>';
} else if (xmlhr.readyState == 4 && xmlhr.status == 200) {
if (xmlhr.responseText) {
resultDiv.innerHTML = xmlhr.responseText;
}
} else if (xmlhr.readyState == 4) {
alert('Invalid response received - Status: ' + xmlhr.status);
}
}
xmlhr.send(params);
}
ytVideoApp.prepareSyndicatedUpload = function(videoTitle, videoCategory, fileContents) {
var filePath = '_scripts/operations.php';
var params = 'operation=create_upload_form' +
'&videoTitle=' + videoTitle +
'&videoCategory=' + videoCategory;
ytVideoApp.sendRequest(filePath, params, ytVideoApp.SYNDICATED_UPLOAD_DIV);
}
_scripts / operations.php:
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_YouTube');
Zend_Loader::loadClass('Zend_Gdata_AuthSub');
Zend_Loader::loadClass('Zend_Gdata_App_Exception');
/*
* The main controller logic.
*
* POST used for all authenticated requests
* otherwise use GET for retrieve and supplementary values
*/
session_start();
setLogging('on');
generateUrlInformation();
if (!isset($_POST['operation'])) {
// if a GET variable is set then process the token upgrade
if (isset($_GET['token'])) {
updateAuthSubToken($_GET['token']);
} else {
if (loggingEnabled()) {
logMessage('reached operations.php without $_POST or $_GET variables set', 'error');
header('Location: add-content.php');
}
}
}
$operation = $_POST['operation'];
switch ($operation) {
....
case 'create_upload_form':
createUploadForm($_POST['videoTitle'],
$_POST['videoCategory'],
$_POST['videoContents']);
break;
....
default:
unsupportedOperation($_POST);
break;
}
function createUploadForm($videoTitle, $videoCategory, $nextUrl = null) {
$httpClient = getAuthSubHttpClient();
$youTubeService = new Zend_Gdata_YouTube($httpClient);
$newVideoEntry = new Zend_Gdata_YouTube_VideoEntry();
$newVideoEntry->setVideoTitle($videoTitle);
//make sure first character in category is capitalized
$videoCategory = strtoupper(substr($videoCategory, 0, 1))
. substr($videoCategory, 1);
$newVideoEntry->setVideoCategory($videoCategory);
// convert videoTags from whitespace separated into comma separated
$tokenHandlerUrl = 'https://gdata.youtube.com/action/GetUploadToken';
try {
$tokenArray = $youTubeService->getFormUploadToken($newVideoEntry, $tokenHandlerUrl);
if (loggingEnabled()) {
logMessage($httpClient->getLastRequest(), 'request');
logMessage($httpClient->getLastResponse()->getBody(), 'response');
}
} catch (Zend_Gdata_App_HttpException $httpException) {
print 'ERROR ' . $httpException->getMessage()
. ' HTTP details<br /><textarea cols="100" rows="20">'
. $httpException->getRawResponseBody()
. '</textarea><br />'
. '<a href="session_details.php">'
. 'click here to view details of last request</a><br />';
return;
} catch (Zend_Gdata_App_Exception $e) {
print 'ERROR - Could not retrieve token for syndicated upload. '
. $e->getMessage()
. '<br /><a href="session_details.php">'
. 'click here to view details of last request</a><br />';
return;
}
$tokenValue = $tokenArray['token'];
$postUrl = $tokenArray['url'];
// place to redirect user after upload
if (!$nextUrl) {
$nextUrl = $_SESSION['homeUrl'];
}
//instead of outputting the form below, send variables (json???) to be interpreted by xmlhr in _js/video_app.js
//print <<< END
//<br />
//<p>url: ${postUrl}?nexturl=${nextUrl}</p>
//<form id="uploadToYouTubeForm" action="temp.php" method="post" enctype="multipart/form-data">
//<input id="uploadToYouTube" name="file" type="file" onchange="autoUploadToYouTube();" /><br/>
//token: <input id="token" name="token" type="text" value="${tokenValue}"/><br/>
//<input value="Manual upload" type="submit" />
//</form>
//END;
//}
したがって、最初のjavascriptは、入力type = "file"のドラッグアンドドロップ(div上)またはchange()イベントをリッスンします。フォームは実際には送信されませんが、データが収集され、ajaxを介してphpスクリプトに送信されます。このスクリプトは、アップロードに必要なトークンとURLを返します。次に、元のPHPスクリプトは、ファイル(およびトークンを含む非表示フィールド)を選択するためのフォームを出力します。その代わりに、URLとトークンを変数として渡し、XMLHttpRequestを使用して、これらの変数をフォームのaction属性に配置し、キーを非表示の入力フィールドの値に設定します。次に、フィールドを介して送信できます$('#uploadToYouTubeForm').submit();
発生する可能性のある唯一の問題は、YouTubeアプリに追加情報を送信することです。それが単に無視されるか、YouTubeが受け入れないフィールド(タイトル、カテゴリ、最大ファイルサイズ)をプログラムで削除する必要があるかもしれません。 ..