I'm having trouble getting Access-Control-Expose-Headers
from a preflight OPTIONS
for a PUT
request working in a local development environment - the browser seems to ignore it and doesn't expose the header listed to Javascript code.
Below is an example site that you can run locally, and look in the console to see that null
is output rather than the my-value
header value returned from the server.
In /etc/hosts
add two domains:
127.0.0.1 locala.test
127.0.0.1 localb.test
save the below python program to cors.py
, and run it by python cors.py
from http.server import BaseHTTPRequestHandler, HTTPServer
class MyServer(BaseHTTPRequestHandler):
# Serves the website that makes the CORS request
# View on http://locala.test:8080/
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write('''
<html>
<head><title>CORS Example</title></head>
<body>
<p>Web page that makes a CORS request</p>
<script>
fetch('http://localb.test:8080/', {
method: 'PUT'
}).then((response) => {
// Outputs null, when it should output x-my-custom
console.log(response.headers.get('x-my-custom'));
})
</script>
</body>
</html>
'''.encode('utf-8'))
# To be accessed via http://localb.test:8080/
def do_OPTIONS(self):
self.send_response(204)
self.send_header("Access-Control-Allow-Origin", "http://locala.test:8080")
self.send_header("Access-Control-Allow-Methods", "PUT")
self.send_header("Access-Control-Expose-Headers", "x-my-custom")
self.end_headers()
# To be accessed via http://localb.test:8080/
def do_PUT(self):
self.send_response(200)
self.send_header("Access-Control-Allow-Origin", "http://locala.test:8080")
self.send_header("x-my-custom", 'my-value')
self.end_headers()
webServer = HTTPServer(('127.0.0.1', 8080), MyServer)
print('Running. Press CTRL C to stop.')
try:
webServer.serve_forever()
except KeyboardInterrupt:
pass
webServer.server_close()
print('Stopped')
and then view it in http://locala.test:8080 in a browser.
CodePudding user response:
The Access-Control-Expose-Headers
header belongs in the response to the actual request, not in the response to the associated preflight request. Adding it to the latter has no effect. See the relevant section of the Fetch standard:
An HTTP response to a CORS request that is not a CORS-preflight request can also include the following header:
Access-Control-Expose-Headers
Indicates which headers can be exposed as part of the response by listing their names.
(my emphasis)