2013-08-28 89 views
3

我正在嘗試使用Amazon S3來存儲我的文件。另外我想用FineUploader上傳圖片到亞馬遜(我使用的是Zend Framework)。在FineUploader上使用Amazon S3時出錯

這是我的看法:

<div id="fineuploader-s3"></div> 

這是我的JavaScript文件:(改鍵/桶名稱)

$(document).ready(function() { 
$('#fineuploader-s3').fineUploaderS3({ 
    request: { 
     // REQUIRED: We are using a custom domain 
     // for our S3 bucket, in this case. You can 
     // use any valid URL that points to your bucket. 
     endpoint: "mybucket.s3.amazonaws.com", 

     // REQUIRED: The AWS public key for the client-side user 
     // we provisioned. 
     accessKey: "mykey" 
    }, 

    // REQUIRED: Path to our local server where requests 
    // can be signed. 
    signature: { 
     endpoint: "/s3/s3demo.php" 
    }, 

    // OPTIONAL: An endopint for Fine Uploader to POST to 
    // after the file has been successfully uploaded. 
    // Server-side, we can declare this upload a failure 
    // if something is wrong with the file. 
    uploadSuccess: { 
     endpoint: "/s3demo.php?success" 
    }, 

    // USUALLY REQUIRED: Blank file on the same domain 
    // as this page, for IE9 and older support. 
    iframeSupport: { 
     localBlankPagePath: "/server/success.html" 
    }, 

    // optional feature 
    retry: { 
     showButton: true 
    }, 

    // optional feature 
    chunking: { 
     enabled: true 
    }, 

    // optional feature 
    resume: { 
     enabled: true 
    }, 

    // optional feature 
    deleteFile: { 
     enabled: true, 
     method: "POST", 
     endpoint: "/s3demo.php" 
    }, 

    // optional feature 
    validation: { 
     itemLimit: 5, 
     sizeLimit: 15000000 
    } 
}); 
}); 

這是在文件夾S3我 's3demo.php' 文件(在公共文件,根文件):(改鍵/ bucketname)

<?php 

// You can remove these two lines if you are not using Fine Uploader's 
// delete file feature 
require 'AWSSDKforPHP/aws.phar'; 
use Aws\S3\S3Client; 

// These assume you have the associated AWS keys stored in 
// the associated system environment variables 
$clientPrivateKey = $_SERVER['mykey']; 
// These two keys are only needed if the delete file feature is enabled 
// or if you are, for example, confirming the file size in a successEndpoint 
// handler via S3's SDK, as we are doing in this example. 
//$serverPublicKey = $_SERVER['PARAM1']; 
//$serverPrivateKey = $_SERVER['PARAM2']; 

// The following variables are used when validating the policy document 
// sent by the uploader. 
$expectedBucketName = "mybucket.s3.amazonaws.com"; 
// $expectedMaxSize is the value you set the sizeLimit property of the 
// validation option. We assume it is `null` here. If you are performing 
// validation, then change this to match the integer value you specified 
// otherwise your policy document will be invalid. 
// http://docs.fineuploader.com/branch/develop/api/options.html#validation-option 
$expectedMaxSize = null; 

$method = getRequestMethod(); 

// This second conditional will only ever evaluate to true if 
// the delete file feature is enabled 
if ($method == "DELETE") { 
    deleteObject(); 
} 
// This is all you really need if not using the delete file feature 
// and not working in a CORS environment 
else if ($method == 'POST') { 

    // Assumes the successEndpoint has a parameter of "success" associated with it, 
    // to allow the server to differentiate between a successEndpoint request 
    // and other POST requests (all requests are sent to the same endpoint in this example). 
    // This condition is not needed if you don't require a callback on upload success. 
    if (isset($_REQUEST["success"])) { 
     verifyFileInS3(); 
    } 
    else { 
     signRequest(); 
    } 
} 

// This will retrieve the "intended" request method. Normally, this is the 
// actual method of the request. Sometimes, though, the intended request method 
// must be hidden in the parameters of the request. For example, when attempting to 
// send a DELETE request in a cross-origin environment in IE9 or older, it is not 
// possible to send a DELETE request. So, we send a POST with the intended method, 
// DELETE, in a "_method" parameter. 
function getRequestMethod() { 

    if ($_POST['_method'] != null) { 
     return $_POST['_method']; 
    } 

    return $_SERVER['REQUEST_METHOD']; 
} 

function getS3Client() { 
    global $serverPublicKey, $serverPrivateKey; 

    return S3Client::factory(array(
     'key' => $serverPublicKey, 
     'secret' => $serverPrivateKey 
    )); 
} 

// Only needed if the delete file feature is enabled 
function deleteObject() { 
    getS3Client()->deleteObject(array(
     'Bucket' => $_POST['bucket'], 
     'Key' => $_POST['key'] 
    )); 
} 

function signRequest() { 
    header('Content-Type: application/json'); 

    $responseBody = file_get_contents('php://input'); 
    $contentAsObject = json_decode($responseBody, true); 
    $jsonContent = json_encode($contentAsObject); 

    $headersStr = $contentAsObject["headers"]; 
    if ($headersStr) { 
     signRestRequest($headersStr); 
    } 
    else { 
     signPolicy($jsonContent); 
    } 
} 

function signRestRequest($headersStr) { 
    if (isValidRestRequest($headersStr)) { 
     $response = array('signature' => sign($headersStr)); 
     echo json_encode($response); 
    } 
    else { 
     echo json_encode(array("invalid" => true)); 
    } 
} 

function isValidRestRequest($headersStr) { 
    global $expectedBucketName; 

    $pattern = "/\/$expectedBucketName\/.+$/"; 
    preg_match($pattern, $headersStr, $matches); 

    return count($matches) > 0; 
} 

function signPolicy($policyStr) { 
    $policyObj = json_decode($policyStr, true); 

    if (isPolicyValid($policyObj)) { 
     $encodedPolicy = base64_encode($policyStr); 
     $response = array('policy' => $encodedPolicy, 'signature' => sign($encodedPolicy)); 
     echo json_encode($response); 
    } 
    else { 
     echo json_encode(array("invalid" => true)); 
    } 
} 

function isPolicyValid($policy) { 
    global $expectedMaxSize, $expectedBucketName; 

    $conditions = $policy["conditions"]; 
    $bucket = null; 
    $parsedMaxSize = null; 

    for ($i = 0; $i < count($conditions); ++$i) { 
     $condition = $conditions[$i]; 

     if (isset($condition["bucket"])) { 
      $bucket = $condition["bucket"]; 
     } 
     else if (isset($condition[0]) && $condition[0] == "content-length-range") { 
      $parsedMaxSize = $condition[2]; 
     } 
    } 

    return $bucket == $expectedBucketName && $parsedMaxSize == (string)$expectedMaxSize; 
} 

function sign($stringToSign) { 
    global $clientPrivateKey; 

    return base64_encode(hash_hmac(
      'sha1', 
      $stringToSign, 
      $clientPrivateKey, 
      true 
     )); 
} 

// This is not needed if you don't require a callback on upload success. 
function verifyFileInS3() { 
    global $expectedMaxSize; 

    $bucket = $_POST["bucket"]; 
    $key = $_POST["key"]; 

    // If utilizing CORS, we return a 200 response with the error message in the body 
    // to ensure Fine Uploader can parse the error message in IE9 and IE8, 
    // since XDomainRequest is used on those browsers for CORS requests. XDomainRequest 
    // does not allow access to the response body for non-success responses. 
    if (getObjectSize($bucket, $key) > $expectedMaxSize) { 
     // You can safely uncomment this next line if you are not depending on CORS 
     header("HTTP/1.0 500 Internal Server Error"); 
     deleteObject(); 
     echo json_encode(array("error" => "File is too big!")); 
    } 
    else { 
     echo json_encode(array("tempLink" => getTempLink($bucket, $key))); 
    } 
} 

// Provide a time-bombed public link to the file. 
function getTempLink($bucket, $key) { 
    $client = getS3Client(); 
    $url = "{$bucket}/{$key}"; 
    $request = $client->get($url); 

    return $client->createPresignedUrl($request, '+15 minutes'); 
} 

function getObjectSize($bucket, $key) { 
    $objInfo = getS3Client()->headObject(array(
      'Bucket' => $bucket, 
      'Key' => $key 
     )); 
    return $objInfo['ContentLength']; 
} 
?> 

我得到這個錯誤:

[FineUploader 3.8.0] Error attempting to parse signature response: SyntaxError: Unexpected token < s3.jquery.fineuploader-3.8.0.min.js:16
[FineUploader 3.8.0] Received an empty or invalid response from the server! s3.jquery.fineuploader-3.8.0.min.js:16
[FineUploader 3.8.0] Policy signing failed. Received an empty or invalid response from the server! s3.jquery.fineuploader-3.8.0.min.js:16

的第一個錯誤表明我s3demo.php文件有問題...(令牌< - >第一我的PHP文件)

響應 - 標題:

Request URL: http://www.link.com/s3/s3demo.php
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept:/
Accept-Encoding:gzip,deflate,sdch
Accept-Language:nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:no-cache
Connection:keep-alive
Content-Length:292
Content-Type:application/json; charset=UTF-8
Cookie:PHPSESSID=
Host:www.link.com
Origin: http://www.link.com
Pragma:no-cache
Referer: http://www.link.com/quiz/design
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36
Request Payloadview source
{expiration:2013-08-28T15:35:56.160Z,…}
conditions: [{acl:private}, {bucket:mybucket}, {Content-Type:image/png}, {success_action_status:200},…] expiration: "2013-08-28T15:35:56.160Z"
Response Headers view source
Connection:Keep-Alive
Content-Length:2504
Content-Type:application/json
Date:Wed, 28 Aug 2013 15:30:55 GMT
Keep-Alive:timeout=5, max=90
Server:Apache/2.2.22 (Debian)
X-Powered-By:PHP/5.5.1-1~dotdeb.1

實際響應:


(!) Notice: Undefined index: _method in /var/www/site/public/s3/s3demo.php on line 79 Call Stack #TimeMemoryFunctionLocation 10.0047235456{main}()../s3demo.php:0 20.0323825744getRequestMethod()../s3demo.php:48
(!) Notice: Undefined index: headers in s3/s3demo.php on line 110 Call Stack #TimeMemoryFunctionLocation 10.0047235456{main}()../s3demo.php:0 20.0325825896signRequest()../s3demo.php:67 {"invalid":true}

回答

1

我不認爲你完全理解文檔或例子。您需要一個服務器端組件來簽署Fine Uploader發送的請求。由於某種原因,您似乎將Fine Uploader指向JSON文件。我猜你從博客文章複製了示例簽名文件,並指出Fine Uploader?示例簽名文件在博客文章中有詳細介紹,可讓您深入瞭解Fine Uploader S3如何爲您爲簡單上傳生成策略文檔。您無需在任何地方存儲此副本。

您需要一個合適的服務器端組件來簽署Fine Uploader至少發送給S3的請求。 Fine Uploader S3在https://github.com/Widen/fine-uploader-server中已經有5個功能全面的服務器端示例。實際上,博客文章鏈接到用node,python,php和java編寫的例子。您還應該仔細閱讀博客文章或文檔。

+0

感謝您的信息!我更新了我的開始帖子,我認爲這是方式,但我的簽名文件仍然出現錯誤... – nielsv

+0

該錯誤表明您的服務器安裝不正確,或者您的簽名文件的路徑不正確。 –

+0

但是'<'表示我的php文件的第一個字符..? – nielsv