我的博客

JavaScript 原生 XMLHttpRequest ajax 实现七牛云私有图片上传(django 后端)

目录
  1. 后端
  2. 前端
    1. 一个参考

后端

后端需要

  1. 获取 upload key 的 api 供前端调用
  2. 接受前端上传成功以后发来的图片的 hash,有这个 hash 以后才能访问到图片
  3. 显示表单的页面 view 函数
  4. 根据 hash 获取真实 url 的 api

view.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from django.http import HttpResponse
from qiniu import Auth
from django.contrib.auth.decorators import login_required

from .models import Image

access_key = ''
secret_key = ''
bucket_name = ''
bucket_url = ''
q = Auth(access_key, secret_key)


@login_required
def get_qiniu_token_api(request):
if request.user.userprofile.user_type != "工作人员":
return HttpResponse('error!', status=400)
token = q.upload_token(bucket_name)
return HttpResponse(token)

@login_required
def get_image_api(request, hash):
if request.user.userprofile.user_type != "工作人员":
return HttpResponse('error!', status=400)
url = q.private_download_url('http://cdn1.xxxx.com/' + hash, 120)
return HttpResponse(url)

@login_required
def create_image_api(request):
if request.user.userprofile.user_type != "工作人员":
return HttpResponse('error!', status=400)
hash = request.GET.get('hash', None)
name = request.GET.get('name', None)
if not hash:
return HttpResponse('error!', status=400)
if not name:
return HttpResponse('请填写名字!', status=400)
Image.objects.create(name=name, hash=hash, user=request.user.userprofile)
return HttpResponse('成功!')

@login_required
def upload_image_page(request):
return render(request, 'upload_image.html')

models.py

1
2
3
4
5
6
7
8
9
from django.db import models
from account.models import UserProfile


class Image(models.Model):
name = models.CharField(max_length=100)
hash = models.CharField(max_length=30)
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, null=True, default=None)
create_time = models.DateTimeField(auto_now_add=True)

前端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<ul class="weui-uploader__files" id="uploaderFiles">

</ul>
<form id="uploadForm" onsubmit="return upload_image()" method="post" enctype="multipart/form-data">
<input id="tokenx" name="token" type="hidden" value="<upload_token>">
<input id="uploaderInput" class="weui-uploader__input" type="file" accept="image/*" multiple="" name="file" onchange="upload_image(this)">
</form>

<script>
function uploadImg() {
let xhr = new XMLHttpRequest();
xhr.open("POST", 'https://upload-z1.qiniup.com', true);
let formData = new FormData(uploadForm);
xhr.send(formData);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
let result = xhr.responseText;
result = JSON.parse(result);
console.log(result);
let xhr2 = new XMLHttpRequest();
xhr2.open("GET", '/api/media/add_hash/?hash=' + result.hash + '&name=' + iname.value, true);
xhr2.send();
xhr2.onreadystatechange = function () {
if (xhr2.readyState === 4) {
we_alert("通知", xhr2.responseText);
let xhr3 = new XMLHttpRequest();
xhr3.open("GET", '/api/media/get_url/' + result.hash + '/', true);
xhr3.send();
xhr3.onreadystatechange = function () {
if (xhr3.readyState === 4) {
uploaderFiles.innerHTML += '<li class="weui-uploader__file" id="weuiuploadfile" style="background-image:url(' + xhr3.responseText + ')"></li>'
iname.value = '';
}
}
}
}
}
}
}


function upload_image() {
if (iname.value.length === 0) {
we_alert("错误!", "请填写名称!")
return false;
}
let xhr = null;
if (window.XMLHttpRequest) { // code for IE7, Firefox, Opera, etc.
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {// code for IE6, IE5
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
if (xhr) {
xhr.open('GET', '/api/media/token/', false);
xhr.send();
if (xhr.status === 200) {
console.log(xhr.responseText);
tokenx.value = xhr.responseText;
uploadImg();
return false;
}
else {
we_alert('错误,无法上传', '');
return false;
}
} else {
we_alert('错误', '你的浏览器不支持 XMLHTTP 请更换浏览器');
}
}
</script>

一个参考

https://blog.csdn.net/ChinaLiu_Kang/article/details/86613453

这个写的挺好的,但是我用会出 400,因为这个 api 只能接受 form 格式的 post 请求。

可以学习图片转 base64 的方法(但我这里没用他这个)

1
2
3
4
5
6
7
8
var reader = new FileReader();
reader.readAsDataURL(uploaderInput.files[0]);
reader.onload = function(e) {
//或者 e.target.result都是一样的,都是base64码
let imgStr = reader.result.split(',')[1];
console.log('需要上传的base64格式图片:' + imgStr);
uploadImg(token, imgStr);
};

评论无需登录,可以匿名,欢迎评论!