使用 AJAX torest 框架上传图片

Posted

技术标签:

【中文标题】使用 AJAX torest 框架上传图片【英文标题】:Uploading images with AJAX torest framework 【发布时间】:2020-11-09 01:18:00 【问题描述】:

我想使用 drf 和 A​​JAX 将图像上传到我的 Django 应用程序 我没有模型要做我只想序列化数据

这里是 serializers.py

first_name = serializers.CharField()
last_name = serializers.CharField()
password1 = serializers.CharField()
password2 = serializers.CharField()
prof_img = serializers.ImageField()
bio = serializers.CharField()
email = serializers.EmailField()

这是views.py

@api_view (['POST']) def register_api(请求): 如果 request.user.is_authenticated: 返回重定向('/')

print('register_api')
# print(request.data)
serialized = RegisterSerializer(data=request.data)
print('hi')
if serialized.is_valid(raise_exception=True):
    print('valid')
    print('data -> ', serialized.data)
    return
print('invalid')

我只想打印数据,一切都被序列化但显示 prof_img =

这是我发送数据的函数

async function register_form_submit(event) 
  event.preventDefault()
  var formElm = event.target
  const myFormData = Object.values(event.target).reduce((obj, field) => 
    obj[field.name] = field.value;
    return obj
  , )
  console.log(myFormData)
  myFormData.prof_img = imgElm.files[0]
  console.log('new -> ', myFormData)

  const csrftoken = getCookie('csrftoken')
  const options = 
    method: 'POST',
    headers: 
      "Content-Type": "application/json",
      "X-CSRFToken": csrftoken
    ,
    body: JSON.stringify(
      myFormData
    )
  
  const resp = await fetch('/accounts/register_api', options)
  console.log(resp)
  console.log(resp.message)
  console.log(resp.status)

我尝试删除 "Content-Type": "application/json",

但随后 Python 控制台显示 Unsupported Media Type: /accounts/register_api

这是我从 settings.py 中截取的

REST_FRAMEWORK = 

'DEFAULT_AUTHENTICATION_CLASSES': DEFAULT_AUTHENTICATION_CLASSES,
'DEFAULT_RENDERER_CLASSES': DEFAULT_RENDERER_CLASSES,
'DEFAULT_PARSER_CLASSES': (
    'rest_framework.parsers.FormParser',
    'rest_framework.parsers.MultiPartParser'
)

请尽量避免使用基于类的序列化程序或基于类的视图

【问题讨论】:

我观察到您尝试在不使用 FormData 对象的情况下发送文件。如果您需要使用 JSON 将文件作为字符串发送,您可能需要使用 FileReader 来获取图像的 Base64 字符串。 FormData 不起作用我使用了 var mydata = new FormData(element) 但它什么也没显示 您尝试过使用 FileReader API 吗? FormData() 需要不同的配置获取。 我不知道 abt fileReader api 你能解释一下吗 【参考方案1】:

此通过 JSON 以 BASE64 字符串形式发送文件。我是你的服务器 PY,你需要解码 base64 来获取二进制文件。

          async function register_form_submit(event) 
                event.preventDefault()
                var formElm = event.target
                const myFormData = Object.values(event.target).reduce((obj, field) => 
                    obj[field.name] = field.value;
                    return obj
                , );


                const toBase64 = file => new Promise((resolve, reject) => 
                        const reader = new FileReader();
                        reader.readAsDataURL(file);
                        reader.onload = () => resolve(reader.result);
                        reader.onerror = error => reject(error);
                    );
                    
                    await toBase64(formElm.files[0]).then(base64=>
                         myFormData.prof_img = base64;
                    ).error(error=>
                        //MANAGE ERROR HERE.
                        myFormData.prof_img="";
                        return;
                    );
                const csrftoken = getCookie('csrftoken')
                const options = 
                    method: 'POST',
                    headers: 
                        headers: 
                          'Accept': 'application/json',
                          'Content-Type': 'application/json',
                          "X-CSRFToken": csrftoken
                    ,
                    body: JSON.stringify(
                            myFormData
                            )
                
                const resp = await fetch('/accounts/register_api', options)
                console.log(resp)
                console.log(resp.message)
                console.log(resp.status)
            

【讨论】:

U=Image 被转换为 base64 和 formdata => prof_img: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD" 但服务器仍然显示Unsupported Media Type: /accounts/register_api。在打印 request.data 添加头文件:> 'Accept': 'application/json', 在你的服务器端python:在解码之前从base64字符串中删除data:image/jpeg;base64。 developer.mozilla.org/en-US/docs/Web/HTTP/Status/415

以上是关于使用 AJAX torest 框架上传图片的主要内容,如果未能解决你的问题,请参考以下文章

SSM框架下,使用ajax请求上传文件(docdocxexcel图片等)

关于使用ajax上传图片问题

laravel框架里用jq实现ajax图片上传

Jersey后端服务接收ajax前端的图片上传

Jersey后端服务接收ajax前端的图片上传

使用 jQuery $.ajax 和 Spring Boot 上传图片的进度条