@@ -27,6 +27,7 @@ class GraphQLView(HTTPMethodView):
2727 middleware = None
2828 batch = False
2929 jinja_env = None
30+ max_age = 86400
3031
3132 _enable_async = True
3233
@@ -79,40 +80,44 @@ async def dispatch_request(self, request, *args, **kwargs):
7980
8081 pretty = self .pretty or show_graphiql or request .args .get ('pretty' )
8182
82- execution_results , all_params = run_http_query (
83- self .schema ,
84- request_method ,
85- data ,
86- query_data = request .args ,
87- batch_enabled = self .batch ,
88- catch = catch ,
89-
90- # Execute options
91- return_promise = self ._enable_async ,
92- root_value = self .get_root_value (request ),
93- context_value = self .get_context (request ),
94- middleware = self .get_middleware (request ),
95- executor = self .get_executor (request ),
96- )
97- awaited_execution_results = await Promise .all (execution_results )
98- result , status_code = encode_execution_results (
99- awaited_execution_results ,
100- is_batch = isinstance (data , list ),
101- format_error = self .format_error ,
102- encode = partial (self .encode , pretty = pretty )
103- )
83+ if request_method != 'options' :
84+ execution_results , all_params = run_http_query (
85+ self .schema ,
86+ request_method ,
87+ data ,
88+ query_data = request .args ,
89+ batch_enabled = self .batch ,
90+ catch = catch ,
91+
92+ # Execute options
93+ return_promise = self ._enable_async ,
94+ root_value = self .get_root_value (request ),
95+ context_value = self .get_context (request ),
96+ middleware = self .get_middleware (request ),
97+ executor = self .get_executor (request ),
98+ )
99+ awaited_execution_results = await Promise .all (execution_results )
100+ result , status_code = encode_execution_results (
101+ awaited_execution_results ,
102+ is_batch = isinstance (data , list ),
103+ format_error = self .format_error ,
104+ encode = partial (self .encode , pretty = pretty )
105+ )
104106
105- if show_graphiql :
106- return await self .render_graphiql (
107- params = all_params [0 ],
108- result = result
107+ if show_graphiql :
108+ return await self .render_graphiql (
109+ params = all_params [0 ],
110+ result = result
111+ )
112+
113+ return HTTPResponse (
114+ result ,
115+ status = status_code ,
116+ content_type = 'application/json'
109117 )
110118
111- return HTTPResponse (
112- result ,
113- status = status_code ,
114- content_type = 'application/json'
115- )
119+ else :
120+ return self .process_preflight (request )
116121
117122 except HttpQueryError as e :
118123 return HTTPResponse (
@@ -157,3 +162,23 @@ def should_display_graphiql(self, request):
157162 def request_wants_html (self , request ):
158163 accept = request .headers .get ('accept' , {})
159164 return 'text/html' in accept or '*/*' in accept
165+
166+ def process_preflight (self , request ):
167+ """ Preflight request support for apollo-client
168+ https://www.w3.org/TR/cors/#resource-preflight-requests """
169+ origin = request .headers .get ('Origin' , '' )
170+ method = request .headers .get ('Access-Control-Request-Method' , '' ).upper ()
171+
172+ if method and method in self .methods :
173+ return HTTPResponse (
174+ status = 200 ,
175+ headers = {
176+ 'Access-Control-Allow-Origin' : origin ,
177+ 'Access-Control-Allow-Methods' : ', ' .join (self .methods ),
178+ 'Access-Control-Max-Age' : str (self .max_age ),
179+ }
180+ )
181+ else :
182+ return HTTPResponse (
183+ status = 400 ,
184+ )
0 commit comments