我正在关注https://devcenter.heroku.com/articles/s3-upload-python的示例,用于将文件从客户端直接上传到s3并出现错误
views.api.sign_s3:
def sign_s3(request):
S3_BUCKET = os.environ.get('S3_BUCKET')
file_name = request.GET.get('file_name',False)
file_type = request.GET.get('file_type',False)
s3 = boto3.client('s3')
presigned_post = s3.generate_presigned_post(
Bucket = S3_BUCKET,
Key = file_name,
Fields = {"acl": "public-read", "Content-Type": file_type},
Conditions = [
{"acl": "public-read"},
{"Content-Type": file_type}
],
ExpiresIn = 3600
)
return json.dumps({
'data': presigned_post,
'url': 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, file_name)
})
settings.py:
os.environ['S3_BUCKET'] = 'mybucketname'
os.environ['AWS_ACCESS_KEY_ID'] = 'myaccesskey'
os.environ['AWS_SECRET_ACCESS_KEY'] = 'mysecretaccesskey'
html文件
<input id="file_input" name="video_files" type="file">
<!-- other html omitted -->
<script>
(function() {
document.getElementById("file_input").onchange = function(){
var files = document.getElementById("file_input").files;
var file = files[0];
if(!file){
return alert("No file selected.");
}
$(files).each(function(i,file){
getSignedRequest(file);
});
};
})();
function getSignedRequest(file){
var xhr = new XMLHttpRequest();
console.log(file);
xhr.open("GET", "/api/sign_s3?file_name="+file.name+"&file_type="+file.type);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200){
var response = JSON.parse(xhr.responseText);
uploadFile(file, response.data, response.url);
}else{
alert("Could not get signed URL.");
}
}
};
xhr.send();
}
function uploadFile(file, s3Data, url){
var xhr = new XMLHttpRequest();
xhr.open("POST", s3Data.url);
var postData = new FormData();
for(key in s3Data.fields){
postData.append(key, s3Data.fields[key]);
}
postData.append('file', file);
xhr.onreadystatechange = function() {
if(xhr.readyState === 4){
if(xhr.status === 200 || xhr.status === 204){
document.getElementById("preview").src = url;
document.getElementById("avatar-url").value = url;
}else{
alert("Could not upload file.");
}
}
};
xhr.send(postData);
}
</script>
回溯:
AttributeError at /api/sign_s3/
'str' object has no attribute 'get'
Request Method: GET
Request URL: http://127.0.0.1:1337/api/sign_s3/? file_name=jam13.mp4&file_type=video/mp4
Django Version: 1.8.5
Exception Type: AttributeError
Exception Value:
'str' object has no attribute 'get'
Exception Location: c:\Python27\lib\site-packages\django\middleware\clickjacking.py in process_response, line 31
Python Executable: c:\Python27\python.exe
Python Version: 2.7.3
...
c:\Python27\lib\site-packages\django\middleware\clickjacking.py in process_response
clickjacking protection techniques should be used if protection in those
browsers is required.
https://en.wikipedia.org/wiki/Clickjacking#Server_and_client
"""
def process_response(self, request, response):
# Don't set it if it's already in the response
if response.get('X-Frame-Options', None) is not None: ...
return response
# Don't set it if they used @xframe_options_exempt
if getattr(response, 'xframe_options_exempt', False):
return response
任何人都知道出了什么问题?
答案 0 :(得分:0)
我认为您将视图返回给视图的方式会造成麻烦。
尝试这样的事情 -
import json
from django.http import HttpResponse, JsonResponse
def sign_s3(request):
#Your View Code Here...
#Finally The Response (Using JsonResponse)...
json_object = {
'data': presigned_post,
'url': 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, file_name)
}
return JsonResponse(json_object)
#Another Response Option (Using HttpResponse)
data = {
'data': presigned_post,
'url': 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, file_name)
}
return HttpResponse(json.dumps(data), content_type = "application/json")