發出 HTTP(S) 要求

區域 ID

REGION_ID 是 Google 根據您在建立應用程式時選取的地區所指派的簡寫代碼。雖然某些區域 ID 可能看起來與常用的國家/地區代碼相似,但此代碼並非對應國家/地區或省份。如果是 2020 年 2 月後建立的應用程式,App Engine 網址會包含 REGION_ID.r。如果是在此日期之前建立的現有應用程式,網址中則可選擇加入地區 ID。

進一步瞭解區域 ID

本頁說明如何透過 App Engine 應用程式發出 HTTP(S) 要求。

預設情況下,App Engine 會使用網址擷取服務發出傳出 HTTP(S) 要求。

如要進一步瞭解要求大小上限和透過網址擷取要求傳送的標頭,請參閱「傳出要求」一文。

如果您已設定無伺服器虛擬私有雲端存取,或使用Sockets API,則需要停止網址擷取處理要求。URL Fetch 會導致對 VPC 網路或 Sockets API 的請求失敗。停用網址擷取後,標準 Python 程式庫會處理 HTTP 要求。如果您需要 URL Fetch 為特定要求提供的功能,可以直接針對這些特定要求使用 urlfetch 程式庫。

發出 HTTP 要求

如要發出傳出 HTTP 要求,請使用 urlfetch.fetch 方法。如要改善程式碼可攜性,您也可以使用 Python 標準程式庫 urlliburllib2httplib 發出 HTTP 要求。在 App Engine 中使用這些程式庫時,這些程式庫會使用 App Engine 的網址擷取服務執行 HTTP 要求。您也可以使用第三方 requests 程式庫,只要將其設為使用 URLFetch 即可。

urlfetch

下列程式碼片段示範如何使用 urlfetch 執行基本的 HTTP GET 要求。首先,請從 App Engine SDK 匯入 urlfetch 程式庫:

from google.appengine.api import urlfetch

接下來,請使用 urlfetch 執行 GET 要求:

url = 'http://www.google.com/humans.txt'
try:
    result = urlfetch.fetch(url)
    if result.status_code == 200:
        self.response.write(result.content)
    else:
        self.response.status_code = result.status_code
except urlfetch.Error:
    logging.exception('Caught exception fetching url')

下列程式碼片段示範如何執行更進階的要求,透過 urlfetch 使用 HTTP POST 要求,提交網頁表單中的資料:

try:
    form_data = urllib.urlencode(UrlPostHandler.form_fields)
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    result = urlfetch.fetch(
        url='http://localhost:8080/submit_form',
        payload=form_data,
        method=urlfetch.POST,
        headers=headers)
    self.response.write(result.content)
except urlfetch.Error:
    logging.exception('Caught exception fetching url')

urllib2

下列程式碼片段示範如何使用 urllib2 執行基本的 HTTP GET 要求。首先,匯入 urllib2 程式庫:

import urllib2

接下來,請使用 urllib2 執行 GET 要求:

url = 'http://www.google.com/humans.txt'
try:
    result = urllib2.urlopen(url)
    self.response.write(result.read())
except urllib2.URLError:
    logging.exception('Caught exception fetching url')

要求

如要使用要求,您必須使用供應商操作說明安裝 requestsrequests-toolbelt

安裝完成後,使用 requests_toolbelt.adapters.appengine 模組將要求設為使用 URLFetch:

import requests
import requests_toolbelt.adapters.appengine

# Use the App Engine Requests adapter. This makes sure that Requests uses
# URLFetch.
requests_toolbelt.adapters.appengine.monkeypatch()

設定完成後,您就能夠正常使用要求。

url = 'http://www.google.com/humans.txt'
response = requests.get(url)
response.raise_for_status()
return response.text

如要進一步瞭解要求對 Google App Engine 的支援情形,請參閱 urllib3.contrib.appenginerequests_toolbelt.appengine 的說明文件。

設定要求逾時

您可以使用 urlfetch.set_default_fetch_deadline() 函式調整預設期限。這個函式會將新的預設期限儲存在執行緒本機變數上,因此必須在例如自訂中介軟體中依照不同要求進行個別設定。

停用重新導向

如果您使用網址擷取服務,則基礎網址擷取服務會根據預設追蹤最多五次重新導向。這些重新導向可能會將機密資訊 (例如授權標頭) 轉寄至重新導向的目的地。如果應用程式不需要 HTTP 重新導向,建議您停用重新導向。

如要指示網址擷取服務不要追蹤重新導向連結,請將 fetch 方法的 follow_redirects 參數設為 False

發出 HTTPS 要求

如要發出 HTTPS 要求,請在呼叫 urlfetch.fetch() 方法時,將 validate_certificate 參數設為 true

發出非同步要求

HTTP(S) 要求預設為同步。如要發出不同步的要求,應用程式必須:

  1. 使用 urlfetch.create_rpc() 建立新的 RPC 物件。這個物件代表您在後續方法呼叫中的非同步呼叫。
  2. 呼叫 urlfetch.make_fetch_call() 即可提出要求。這個方法需要將 RPC 物件與要求目標的網址做為參數。
  3. 呼叫 RPC 物件的 get_result() 方法。這個方法會在要求成功時傳回結果物件;如果要求期間發生錯誤,則會發出例外狀況。

下列程式碼片段示範如何從 Python 應用程式建立基本的非同步要求。首先,從 App Engine SDK 匯入 urlfetch 程式庫:

from google.appengine.api import urlfetch

接下來,請使用 urlfetch 提出非同步要求:

rpc = urlfetch.create_rpc()
urlfetch.make_fetch_call(rpc, 'http://www.google.com/')

# ... do other things ...
try:
    result = rpc.get_result()
    if result.status_code == 200:
        text = result.content
        self.response.write(text)
    else:
        self.response.status_int = result.status_code
        self.response.write('URL returned status code {}'.format(
            result.status_code))
except urlfetch.DownloadError:
    self.response.status_int = 500
    self.response.write('Error fetching URL')

設定要求逾時

如要為要求設定逾時,請在建立 RPC 物件時設定 urlfetch.create_rpc() 方法的 deadline 參數。

使用回呼函式

您可以針對遠端程序呼叫 (RPC) 物件定義回呼函式。當應用程式在物件上呼叫方法 (例如 wait()checksuccess()get_result()) 時,系統會呼叫這個函式,這會導致物件等待要求完成。

如要使用回呼函式處理擷取呼叫的結果:

  1. 建立輔助函式來定義回呼範圍。
  2. 建立處理常式函式以處理擷取呼叫的結果。
  3. 將 RPC 物件的 callback 屬性設為輔助函式。

以下程式碼片段示範如何叫用回呼函式:

def handle_result(rpc):
    result = rpc.get_result()
    self.response.write(result.content)
    logging.info('Handling RPC in callback: result {}'.format(result))

urls = ['http://www.google.com',
        'http://www.github.com',
        'http://www.travis-ci.org']
rpcs = []
for url in urls:
    rpc = urlfetch.create_rpc()
    rpc.callback = functools.partial(handle_result, rpc)
    urlfetch.make_fetch_call(rpc, url)
    rpcs.append(rpc)

# ... do other things ...

# Finish all RPCs, and let callbacks process the results.

for rpc in rpcs:
    rpc.wait()

logging.info('Done waiting for RPCs')

發出要求至其他 App Engine 應用程式

發出要求至其他 App Engine 應用程式時,App Engine 應用程式必須在要求中加入 X-Appengine-Inbound-Appid 標頭以表明自己的身分。如果您指示網址擷取服務不要追蹤重新導向,App Engine 會自動在要求中加入這個標頭。

如要瞭解如何停用重新導向功能,請參閱「停用重新導向功能」。

後續步驟

如要瞭解網址擷取服務,例如透過網址擷取要求傳送的標頭,請參閱傳出要求一文。