Python 2.7 已終止支援,並將於 2026 年 1 月 31 日
淘汰。淘汰後,您將無法部署 Python 2.7 應用程式,即使貴機構先前曾使用機構政策重新啟用舊版執行階段的部署作業,也無法部署。現有的 Python 2.7 應用程式在
淘汰日期過後,仍會繼續執行並接收流量。建議您
改用系統支援的最新 Python 版本。
webapp Blobstore 處理常式
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
webapp 包含能夠與 Blobstore API 搭配使用的要求處理常式類別。BlobstoreUploadHandler
所提供的邏輯,可用於剖析透過 Blobstore 傳送至
BlobInfo
記錄的上傳要求以供後續處理。 BlobstoreDownloadHandler
可輕鬆從任何路徑提供 Blobstore 值。
BlobstoreUploadHandler
使用者或應用程式管理員上傳檔案後,系統就會將值新增至 Blobstore。
應用程式會發布網路表單,其中包含檔案上傳欄位和表單動作,將上傳內容導向 Blobstore。為了取得表單動作網址,應用程式會呼叫函式 (create_upload_url()),為其傳送使用者上傳檔案時呼叫的應用程式處理常式網址。網頁應用程式可以使用 BlobstoreUploadHandler
類別的子類別,做為這個網址的處理常式。
get_uploads()
方法會傳回 BlobInfo 物件的清單,代表要求中的各個上傳檔案。每個物件都包含上傳值的 Blobstore 金鑰,以及檔案名稱和檔案大小等中繼資料。每個上傳檔案在資料儲存庫中也會有包含上述資訊的對應實體,以便您在取得 blob 金鑰後進一步擷取 BlobInfo 物件,或是透過中繼資料欄位執行資料儲存庫查詢。上傳處理常式會直接從要求資料剖析此資訊,而不會從資料儲存庫進行剖析。
根據預設,get_uploads()
會傳回要求中所有上傳檔案的 BlobInfo 物件。此方法也接受 field_name
引數,以取得指定檔案上傳欄位的單一檔案 (或多個檔案)。傳回的值一律為清單,也有可能會是空白清單。
搭配 Google Cloud Storage 使用 BlobstoreUploadHandler
如果您使用這個上傳處理常式搭配 Cloud Storage,您將需要取得並儲存完整的 Cloud Storage 物件檔案名稱,因為必須要有完整名稱才可再次從 Cloud Storage 中擷取檔案。
請使用 get_file_infos
函式,傳回對應至各個上傳的 FileInfo 記錄清單。完整的 Cloud Storage 物件名稱、內容類型、建立時間和其他資料都可在 FileInfo
中找到。(詳情請參閱相關連結)。
BlobstoreDownloadHandler
如要提供 Blobstore 值,應用程式會將 X-AppEngine-BlobKey
標頭設為字串形式的 Blobstore 鍵值。App Engine 在回應中處理此標頭時,將會以回應本文的形式傳遞 blob 值。webapp 處理常式類別 BlobstoreDownloadHandler
可讓您輕鬆在回應中設定這個值。
send_blob()
方法會將 BlobKey 物件、字串金鑰或 BlobInfo 做為 blob_key_or_info
引數,並設定回應資料,以便為使用者提供 blob 值。這個方法會採用選用的 content_type
引數,該引數會覆寫所儲存 blob 值的 MIME 內容類型。根據預設,提供的 blob 還會包含由上傳用戶端設定的內容類型、衍生自檔案名稱的內容類型,或是一般類型 (如果沒有其他可用的類型資訊)。
send_blob()
方法接受 save_as
引數,該引數可決定 blob 資料要以原始回應資料或以包含檔案名稱的 MIME 附件形式傳送。如果引數為字串,則 blob 會以附件形式傳送,而字串值會作為檔案名稱。如果 True
和 blob_key_or_info
為 BlobInfo
物件,則會使用來自物件的檔案名稱。根據預設,blob 資料會以回應本文的形式傳送,而非以 MIME 附件的形式傳送。
Blobstore 支援根據位元組索引範圍所述,僅傳送部分值,而非完整值。有兩種方法可將位元組索引範圍提供給 BlobstoreDownloadHandler
的 send_blob()
方法。第一個方法是使用引數 start
和 end
指定範圍:
# Send the first 1,000 bytes of the value.
self.send_blob(key, start=0, end=999)
根據預設,BlobstoreDownloadHandler
會遵守要求中的 range
標頭。如要封鎖對原始範圍標頭的使用,請為 send_blob()
提供引數 use_range=False
:
# Send the full value of the blob and
# block the "range" header.
self.send_blob(key, use_range=False)
range
標頭的值是標準的 HTTP 位元組範圍。BlobstoreDownloadHandler
使用 webob.byterange 剖析這個標頭值。
完整的應用程式範例
在下列的範例應用程式中,應用程式的主要網址會載入可用來向使用者要求上傳檔案的表單,接著上傳處理常式會立即呼叫下載處理常式以提供資料。此作法是為了要簡化範例應用程式的內容。就實務而言,您可能不會使用主要網址來要求上傳資料,也不會立即提供剛剛才上傳的 blob。
除非另有註明,否則本頁面中的內容是採用創用 CC 姓名標示 4.0 授權,程式碼範例則為阿帕契 2.0 授權。詳情請參閱《Google Developers 網站政策》。Java 是 Oracle 和/或其關聯企業的註冊商標。
上次更新時間:2025-09-04 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["難以理解","hardToUnderstand","thumb-down"],["資訊或程式碼範例有誤","incorrectInformationOrSampleCode","thumb-down"],["缺少我需要的資訊/範例","missingTheInformationSamplesINeed","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-09-04 (世界標準時間)。"],[[["\u003cp\u003e\u003ccode\u003eBlobstoreUploadHandler\u003c/code\u003e is used to manage file uploads to the Blobstore, parsing upload requests and providing \u003ccode\u003eBlobInfo\u003c/code\u003e objects containing data about each file.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003eget_uploads()\u003c/code\u003e method retrieves a list of \u003ccode\u003eBlobInfo\u003c/code\u003e objects for uploaded files, offering options to filter by specific file upload fields.\u003c/p\u003e\n"],["\u003cp\u003eWhen using \u003ccode\u003eBlobstoreUploadHandler\u003c/code\u003e with Google Cloud Storage, \u003ccode\u003eget_file_infos\u003c/code\u003e should be used to get a \u003ccode\u003eFileInfo\u003c/code\u003e record, in order to obtain the full cloud storage object name.\u003c/p\u003e\n"],["\u003cp\u003e\u003ccode\u003eBlobstoreDownloadHandler\u003c/code\u003e facilitates serving Blobstore values by setting the \u003ccode\u003eX-AppEngine-BlobKey\u003c/code\u003e header, allowing you to serve blobs directly to users from a specific path.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003esend_blob()\u003c/code\u003e method in \u003ccode\u003eBlobstoreDownloadHandler\u003c/code\u003e provides options to serve blobs as raw data or as a MIME attachment with a filename, and supports sending partial blob data via byte ranges.\u003c/p\u003e\n"]]],[],null,["# webapp Blobstore Handlers\n\nwebapp includes request handler classes for working with the\n[Blobstore API](/appengine/docs/legacy/standard/python/blobstore). `BlobstoreUploadHandler`\nprovides logic for parsing the upload request passed via the Blobstore into\n[BlobInfo](/appengine/docs/legacy/standard/python/refdocs/google.appengine.ext.blobstore.blobstore#google.appengine.ext.blobstore.blobstore.BlobInfo)\nrecords for further processing. `BlobstoreDownloadHandler` makes it easy to serve\nBlobstore values from any path.\n\nBlobstoreUploadHandler\n----------------------\n\nValues are added to the Blobstore via file uploads posted by users or administrators of the app.\nThe app posts a web form with a file upload field and a form action that directs the upload to the\nBlobstore. The app gets the form action URL by calling a function\n([create_upload_url()](/appengine/docs/legacy/standard/python/refdocs/google.appengine.ext.blobstore.blobstore#google.appengine.ext.blobstore.blobstore.create_upload_url)),\npassing it the URL of an app handler that gets called when users upload files. A webapp\napplication can use a subclass of the `BlobstoreUploadHandler` class as the handler for\nthis URL.\n\nThe `get_uploads()` method returns a list of\n[BlobInfo](/appengine/docs/legacy/standard/python/refdocs/google.appengine.ext.blobstore.blobstore#google.appengine.ext.blobstore.blobstore.BlobInfo)\nobjects, one for each uploaded file in the request. Each object contains the Blobstore key for\nthe uploaded value, as well as metadata such as the filename and size. Each uploaded file also\nhas a corresponding entity in the datastore with this information, so you can fetch the BlobInfo\nobject later given a blob key, or perform a datastore query over the metadata fields. The upload\nhandler parses this information directly from the request data, not the datastore.\n\nBy default, `get_uploads()` returns BlobInfo objects for all uploaded files in the\nrequest. The method also accepts a `field_name` argument to get just the file (or\nfiles) for a given file upload field. The return value is always a list, possibly an empty list. \n\n class PhotoUploadHandler(blobstore_handlers.BlobstoreUploadHandler):\n def post(self):\n upload = self.get_uploads()[0]\n user_photo = UserPhoto(\n user=users.get_current_user().user_id(),\n blob_key=upload.key())\n user_photo.put()\n\n self.redirect('/view_photo/%s' % upload.key())\n\n### Using `BlobstoreUploadHandler` with Google Cloud Storage\n\nIf you use this upload handler with Cloud Storage, you'll need to get and store the full\nCloud Storage object file name, since this is required to retrieve the file again from Cloud Storage.\nUse the function `get_file_infos`, which returns a list of\n[FileInfo](/appengine/docs/legacy/standard/python/refdocs/google.appengine.ext.blobstore.blobstore#google.appengine.ext.blobstore.blobstore.FileInfo) records\ncorresponding to each upload. The full Cloud Storage object name, content type, creation\ntime, and other data are available in the `FileInfo`. (See the link for complete details.)\n\nBlobstoreDownloadHandler\n------------------------\n\nTo serve a Blobstore value, the application sets the `X-AppEngine-BlobKey` header to\nthe value of a Blobstore key, in string form. When App Engine sees this header in the response,\nit serves the value of the blob as the body of the response. The webapp handler class\n`BlobstoreDownloadHandler` makes it easy to set this value in the response.\n\nThe `send_blob()` method takes a\n[BlobKey](/appengine/docs/legacy/standard/python/refdocs/google.appengine.ext.blobstore.blobstore#google.appengine.ext.blobstore.blobstore.BlobKey)\nobject, a string key, or a\n[BlobInfo](/appengine/docs/legacy/standard/python/refdocs/google.appengine.ext.blobstore.blobstore#google.appengine.ext.blobstore.blobstore.BlobInfo)\nas the `blob_key_or_info` argument, and sets the response data so that the blob value\nwill be served to the user. The method takes an optional `content_type` argument which\noverrides the MIME content type of the stored blob value. By default, the blob is served with the\ncontent type set by the client that uploaded it, a content type derived from the filename, or a\ngeneric type if no other type information is available.\n\nThe `send_blob()` method accepts a `save_as` argument that determines\nwhether the blob data is sent as raw response data or as a MIME attachment with a filename. If\nthe argument is a string, the blob is sent as an attachment, and the string value is used as\nthe filename. If `True` and `blob_key_or_info` is a `BlobInfo`\nobject, the filename from the object is used. By default, the blob data is sent as the body of\nthe response and not as a MIME attachment. \n\n class ViewPhotoHandler(blobstore_handlers.BlobstoreDownloadHandler):\n def get(self, photo_key):\n if not blobstore.get(photo_key):\n self.error(404)\n else:\n self.send_blob(photo_key)\n\nThe Blobstore supports sending just part of a value instead of the full value, described as a range of byte indexes. You can provide a byte index range to `BlobstoreDownloadHandler`'s `send_blob()` method in two ways. The first is to specify the range as the arguments `start` and `end`: \n\n```python\n # Send the first 1,000 bytes of the value.\n self.send_blob(key, start=0, end=999)\n```\n\nBy default, the `BlobstoreDownloadHandler` honors the `range` header in the request. If you wish to block use of the original range header, provide the parameter `use_range=False` to `send_blob()`: \n\n```python\n # Send the full value of the blob and\n # block the \"range\" header.\n self.send_blob(key, use_range=False)\n```\n\nThe value of the `range` header is a standard [HTTP byte range](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html). `BlobstoreDownloadHandler` uses [webob.byterange](http://pythonpaste.org/webob/modules/webob.html) to parse this header value.\n\nComplete sample application\n---------------------------\n\nIn the following sample application, the application's main URL loads the form that asks the user\nfor a file to upload, and the upload handler immediately calls the download handler to serve the\ndata. This is to simplify the sample application. In practice, you would probably not use the main\nURL to request upload data, nor would you immediately serve a blob you had just uploaded. \n\n from google.appengine.api import users\n from google.appengine.ext import blobstore\n from google.appengine.ext import ndb\n from google.appengine.ext.webapp import blobstore_handlers\n import webapp2\n\n\n # This datastore model keeps track of which users uploaded which photos.\n class UserPhoto(ndb.Model):\n user = ndb.StringProperty()\n blob_key = ndb.BlobKeyProperty()\n\n\n class PhotoUploadFormHandler(webapp2.RequestHandler):\n def get(self):\n upload_url = blobstore.create_upload_url('/upload_photo')\n # To upload files to the blobstore, the request method must be \"POST\"\n # and enctype must be set to \"multipart/form-data\".\n self.response.out.write(\"\"\"\n \u003chtml\u003e\u003cbody\u003e\n \u003cform action=\"{0}\" method=\"POST\" enctype=\"multipart/form-data\"\u003e\n Upload File: \u003cinput type=\"file\" name=\"file\"\u003e\u003cbr\u003e\n \u003cinput type=\"submit\" name=\"submit\" value=\"Submit\"\u003e\n \u003c/form\u003e\n \u003c/body\u003e\u003c/html\u003e\"\"\".format(upload_url))\n\n\n class PhotoUploadHandler(blobstore_handlers.BlobstoreUploadHandler):\n def post(self):\n upload = self.get_uploads()[0]\n user_photo = UserPhoto(\n user=users.get_current_user().user_id(),\n blob_key=upload.key())\n user_photo.put()\n\n self.redirect('/view_photo/%s' % upload.key())\n\n\n class ViewPhotoHandler(blobstore_handlers.BlobstoreDownloadHandler):\n def get(self, photo_key):\n if not blobstore.get(photo_key):\n self.error(404)\n else:\n self.send_blob(photo_key)\n\n\n app = webapp2.WSGIApplication([\n ('/', PhotoUploadFormHandler),\n ('/upload_photo', PhotoUploadHandler),\n ('/view_photo/([^/]+)?', ViewPhotoHandler),\n ], debug=True)"]]