在球拍中,如何允许文件上传到Web服务器?

时间:2013-12-14 21:49:17

标签: file-upload racket

我正在尝试使用Racket的文件上传小程序(http://docs.racket-lang.org/web-server/formlets.html)启用文件上传到Web服务器。麻烦的是,formlet-process只返回文件的名称而不是其内容。

这是我到目前为止所拥有的:

#lang web-server/insta
(require web-server/formlets
         web-server/http
         xml)

; start: request -> doesn't return
(define (start request)
  (show-page request))

; show-page: request -> doesn't return
(define (show-page request)
  ; Response generator
  (define (response-generator embed/url)
    (response/xexpr
     `(html 
       (head (title "File upload example"))
       (body (h1 "File upload example"))
       (form 
        ([action ,(embed/url upload-handler)])
        ,@(formlet-display file-upload-formlet)
        (input ([type "submit"] [value "Upload"]))))))

  (define (upload-handler request)
    (define a-file (formlet-process file-upload-formlet request))
    (display a-file)
    (response/xexpr
     `(html
       (head (title "File Uploaded"))
       (body (h1 "File uploaded")
             (p "Some text here to say file has been uploaded")))))

  (send/suspend/dispatch response-generator))


; file-upload-formlet: formlet (binding?)
(define file-upload-formlet
  (formlet
   (div ,{(required (file-upload)) . => . a-file})
   a-file))

在这种情况下,a-file被设置为带有文件名的字节字符串,而不是文件的内容。如何获取文件的内容以便将其写入服务器上的文件?

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

好的,这是有效的,但我不确定这是最好的做事方式。基本上我不得不

  1. 将method =“POST”和enctype =“multipart / form-data”添加到表单字段html(是的,小学生错误以省略这些,但我对这些东西不熟悉)
  2. 使用binding:file-filename和binding:file-contents从文件上传小组返回的绑定中提取文件名和内容。
  3. 有助于解决这个问题的参考文献是 http://lists.racket-lang.org/users/archive/2009-August/034925.htmlhttp://docs.racket-lang.org/web-server/http.html

    所以这是工作代码。显然,WORKINGDIR需要设置为一些工作路径。

    #lang web-server/insta
    (require web-server/formlets)
    
     ; start: request -> doesn't return
    (define (start request)
      (show-page request))
    
    ; show-page: request -> doesn't return
    (define (show-page request)
      ; Response generator
      (define (response-generator embed/url)
        (response/xexpr
         `(html 
           (head (title "File upload example"))
           (body (h1 "File upload example"))
           (form 
            ([action ,(embed/url upload-handler)]
             [method "POST"]
             [enctype "multipart/form-data"])
            ,@(formlet-display file-upload-formlet)
            (input ([type "submit"] [value "Upload"]))))))
    
      (define (upload-handler request)
        (define-values (fname fcontents)
          (formlet-process file-upload-formlet request))
        (define save-name (string-append "!uploaded-" fname))
        (current-directory WORKINGDIR)
        (display-to-file fcontents save-name #:exists 'replace)
        (response/xexpr
         `(html
           (head (title "File Uploaded"))
           (body (h2 "File uploaded")
                 (p ,fname)
                 (h2 "File size (bytes)")
                 (p ,(number->string (file-size save-name)))))))
    
      (send/suspend/dispatch response-generator))
    
    
    ; file-upload-formlet: formlet (binding?)
    (define file-upload-formlet
      (formlet
       (div ,{(file-upload) . => . binds})
       ; (formlet-process file-upload-formlet request)
       ; returns the file name and contents:
       (let
           ([fname (bytes->string/utf-8 (binding:file-filename binds))]
            [fcontents (binding:file-content binds)])
         (values fname fcontents))))