如何在GAE的webapp2中将子目录映射至其他服务器?
Absolutely, you can pull this off using App Engine's app.yaml routing and a webapp2 proxy handler—no Apache or .htaccess needed. Here's a step-by-step breakdown to make it work:
1. Configure app.yaml for Routing
First, update your app.yaml to prioritize requests to /forum/* and route them to a separate webapp2 app (we'll build this next). Make sure this handler comes before your main site's catch-all route, since App Engine matches routes in order:
runtime: python27 api_version: 1 threadsafe: true # Route forum traffic first handlers: - url: /forum/.* script: forum_proxy.app # Main site routes (keep your existing main app handler here) - url: /.* script: main.app
2. Build the webapp2 Proxy Handler
Create a new file called forum_proxy.py—this will act as a reverse proxy, forwarding all /forum/ requests to your GCE forum instance. We'll use App Engine's built-in urlfetch service to handle the forwarding:
import webapp2 from google.appengine.api import urlfetch class ForumProxyHandler(webapp2.RequestHandler): def _proxy_request(self, path, method): # Replace this with your GCE forum's actual base URL (include port if needed) GCE_FORUM_BASE = "http://your-gce-instance-ip-or-internal-domain" target_url = f"{GCE_FORUM_BASE}/forum/{path}" try: # Fetch the resource from GCE payload = self.request.body if method in (urlfetch.POST, urlfetch.PUT) else None response = urlfetch.fetch( url=target_url, method=method, payload=payload, headers=self.request.headers, follow_redirects=False ) # Pass through response headers to the client for header_name, header_value in response.headers.items(): self.response.headers[header_name] = header_value # Fix internal redirects to point to your subdirectory instead of GCE's URL if "Location" in self.response.headers: old_location = self.response.headers["Location"] self.response.headers["Location"] = old_location.replace( f"{GCE_FORUM_BASE}/forum", "https://example.com/forum" # Replace with your actual domain/subdirectory ) # Pass through status code and content self.response.status_int = response.status_code self.response.write(response.content) except urlfetch.Error: self.response.status_int = 500 self.response.write("Failed to connect to the forum server.") # Handle all common HTTP methods def get(self, path): self._proxy_request(path, urlfetch.GET) def post(self, path): self._proxy_request(path, urlfetch.POST) def put(self, path): self._proxy_request(path, urlfetch.PUT) def delete(self, path): self._proxy_request(path, urlfetch.DELETE) # Define the route pattern for forum requests app = webapp2.WSGIApplication([ (r"/forum/(.*)", ForumProxyHandler), ], debug=False) # Disable debug in production!
3. Critical Setup Notes
- Network Access: Ensure your GCE instance allows incoming traffic from App Engine. If your GCE is in a VPC, configure serverless VPC access so App Engine can reach it. Alternatively, set firewall rules to allow traffic from App Engine's IP ranges.
- HTTPS: If your main GAE domain uses HTTPS, make sure your GCE forum either supports HTTPS or you configure the proxy to forward over HTTPS (update
GCE_FORUM_BASEto usehttps://). Otherwise, browsers will throw mixed-content warnings. - Static Assets: The proxy will handle static files (CSS, JS, images) automatically, but consider adding caching headers in your GCE forum's response to reduce redundant proxy requests.
- Session/Cookies: If your forum uses cookies, ensure the
Domainattribute of the cookies is set toexample.com(not your GCE's IP) so they work across the subdirectory.
4. Test It Out
Deploy your updated GAE app, then visit https://example.com/forum—you should see your GCE-hosted forum load as if it's part of your main domain's subdirectory.
内容的提问来源于stack exchange,提问作者Occam

