Django2:提交blob并将其存储为图像文件

Django2:提交blob并将其存储为图像文件,django,django-models,django-views,blob,Django,Django Models,Django Views,Blob,在阅读了教程之后,我做了一些Django项目,但我绝对不是Django方面的专家 我正在尝试拍摄当前页面的截图并将其存储(如果不存在的话) 为了实现这一目标,我们需要做几件事: 函数获取当前页面的屏幕截图 函数将此图像异步发布到应存储它的视图 存储已发布图像的视图 但是,屏幕截图函数会导致Blob,我在获取Django视图以正确处理此问题时遇到问题 此处提供了一个演示项目: 截图功能 const屏幕截图=(函数(){ 函数urlsToAbsolute(节点列表){ 如果(!节点列表长度){ 返回

在阅读了教程之后,我做了一些Django项目,但我绝对不是Django方面的专家

我正在尝试拍摄当前页面的截图并将其存储(如果不存在的话)

为了实现这一目标,我们需要做几件事:

  • 函数获取当前页面的屏幕截图
  • 函数将此图像异步发布到应存储它的视图
  • 存储已发布图像的视图
  • 但是,屏幕截图函数会导致Blob,我在获取Django视图以正确处理此问题时遇到问题

    此处提供了一个演示项目:

    截图功能
    const屏幕截图=(函数(){
    函数urlsToAbsolute(节点列表){
    如果(!节点列表长度){
    返回[];
    }
    var attrName='href';
    if(nodeList[0]。\uuuu proto\uuuu===HTMLImageElement.prototype
    ||节点列表[0]。uuu proto_uuu==HTMLScriptElement.prototype){
    attrName='src';
    }
    nodeList=[].map.call(nodeList,function(el,i){
    var attr=el.getAttribute(attrName);
    如果(!attr){
    返回;
    }
    var absURL=/^(https?|数据):/i.test(attr);
    if(absURL){
    返回el;
    }否则{
    返回el;
    }
    });
    返回节点列表;
    }
    函数addOnPageLoad_u382;(){
    window.addEventListener('DOMContentLoaded',函数(e){
    var scrollX=document.documentElement.dataset.scrollX | | 0;
    var scrollY=document.documentElement.dataset.scrollY | | 0;
    scrollTo(scrollX,scrollY);
    });
    }
    函数capturePage(){
    urlsToAbsolute(document.images);
    urlsToAbsolute(document.queryselectoral(“link[rel='stylesheet']”);
    var屏幕截图=document.documentElement.cloneNode(true);
    var b=document.createElement('base');
    b、 href=document.location.protocol+'/'+location.host;
    var head=screenshot.querySelector('head');
    头。插入前(b,头。第一个孩子);
    screenshot.style.pointerEvents='none';
    screenshot.style.overflow='hidden';
    screenshot.style.webkitUserSelect='none';
    screenshot.style.mozzuserselect='none';
    screenshot.style.msUserSelect='none';
    screenshot.style.oUserSelect='none';
    screenshot.style.userSelect='none';
    screenshot.dataset.scrollX=window.scrollX;
    screenshot.dataset.scrollY=window.scrollY;
    var script=document.createElement('script');
    script.textContent='('+addOnPageLoad_uz.toString()+')();';
    screenshot.querySelector('body').appendChild(脚本);
    var blob=新blob([screenshot.outerHTML]{
    键入:“text/html”
    });
    返回斑点;
    }
    返回捕获页面
    })()
    
    用于异步post Blob的函数
    函数setupAjaxWithCSRFToken(){
    //使用jQuery
    var csrftoken=jQuery(“[name=csrfmiddlewaretoken]”)。val();
    函数csrfSafeMethod(方法){
    //这些HTTP方法不需要CSRF保护
    返回(/^(获取|头|选项|跟踪)$/.test(方法));
    }
    //设置csrf头
    $.ajaxSetup({
    发送前:功能(xhr、设置){
    如果(!csrfSafeMethod(settings.type)&&!this.crossDomain){
    setRequestHeader(“X-CSRFToken”,CSRFToken);
    }
    }
    });
    }
    函数asyncSubmitBlob(url,blob){
    var fd=新FormData();
    fd.append('image',blob);
    $.ajax({
    url:url,
    类型:“POST”,
    数据:fd,
    contentType:false,
    processData:false,
    成功:函数(响应){console.log(响应)},
    错误:函数(数据){console.log(数据)}
    })
    }
    

    因此,要提交当前页面的屏幕截图:

    setupAjaxWithCSRFToken()
    const page=window.location.pathname;
    const blob_url=“{%url”我的应用程序:post_blob''替换“%”。替换(/REPLACE/,page='/'?'':page)
    asyncSubmitBlob(blob_url,屏幕截图())
    
    查看以存储已发布的blob图像 url.py

    型号.py

    但我似乎无法忠实地捕捉和找回这个斑点

    许多存储blob的S.O.问题使用带有
    import base64
    的模型方法对blob进行编码和解码。甚至有人建议使用
    二进制字段
    。然而,Django的文档明确指出,
    BinaryField
    并不能替代静态文件的处理

    那么我怎样才能做到这一点呢

    我发现S.O.的帖子有助于实现这一目标

    目前尚不清楚您需要帮助修复的管道中到底有什么。您的blob数据似乎是
    text/html
    ,而不是图像
    var blob=newblob([screenshot.outerHTML],{type:'text/html'})@HåkenLid嗯,这是html节点的文本…为什么要使用blob作为文本?可以使用将站点渲染到客户端和图像客户端。请注意,生成的屏幕截图可能与浏览器中的屏幕截图有所不同。@HåkenLid当我尝试它时,它只截取了适合浏览器视图的屏幕截图(不是溢出),我希望溢出。也许这已经改变了。。。
    
    ...
    from django.urls import include, path
    ...
    app_name='my-app'
    url_patterns=[
      ...
      path('post_blob/', views.post_blob, {'page':'/'},name='post_blob'),
      path('post_blob/<page>', views.post_blob,name='post_blob'),
      ...
    ]
    
    from .models import PageBlob
    ...
    def post_blob(request, page):
        if request.FILES: # save screenshot of specified page
            try:
    
                pb = PageBlob.objects.all().filter(page=page))
                if not pb.count():
                    pb = PageBlob()
                    pb.page = page
                    pb.blob = request.FILES['image']
                    pb.save()
    
    
                    return HttpResponse('Blob Submitted')
            except:
                return HttpResponse('[App::my-app]\tError when requesting page_image({page})'.format(page=page))
        else: # return screenshot of requested page
            try:
                # get objects storing screenshot for requested page
                pb = PageBlob.objects.all().filter(page=page)
                # if one exists
                if pb.count():
                    pb = pb[0]
    
                    ## this just returns the string literal "blob"
                    return HttpResponse(str(pb.blob))
    
    
                return HttpResponse('[App::my-app]\tNo blob for {page}'.format(page=page))
            except:
                return HttpResponse('[App::my-app]\tError when trying to retrieve blob for {page}'.format(page=page))
        return HttpResponse('Another response')
    
    class PageBlob(models.Model):
        page = models.CharField(max_length=500)
        blob = models.TextField(db_column='data', blank=True)