{"id":16990477,"url":"https://github.com/gabrielweyer/cors","last_synced_at":"2025-04-12T03:32:11.653Z","repository":{"id":40409513,"uuid":"133128579","full_name":"gabrielweyer/cors","owner":"gabrielweyer","description":"Illustrates CORS preflight and impact of Access-Control-Max-Age header.","archived":false,"fork":false,"pushed_at":"2024-11-03T00:36:40.000Z","size":4197,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-11-03T01:20:02.592Z","etag":null,"topics":["azure-static-web-apps","cors","github-actions"],"latest_commit_sha":null,"homepage":"https://salmon-pond-0870a1e00.2.azurestaticapps.net/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gabrielweyer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-12T08:37:45.000Z","updated_at":"2024-11-03T00:36:43.000Z","dependencies_parsed_at":"2024-01-02T01:07:21.939Z","dependency_job_id":"b35e0546-5212-43af-9cee-d0f5a2c5064f","html_url":"https://github.com/gabrielweyer/cors","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrielweyer%2Fcors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrielweyer%2Fcors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrielweyer%2Fcors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrielweyer%2Fcors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gabrielweyer","download_url":"https://codeload.github.com/gabrielweyer/cors/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223494315,"owners_count":17154526,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure-static-web-apps","cors","github-actions"],"created_at":"2024-10-14T03:10:14.354Z","updated_at":"2024-11-07T10:04:47.756Z","avatar_url":"https://github.com/gabrielweyer.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CORS\n\n[![Build Status][github-actions-shield]][github-actions]\n\nHosted at \u003chttps://salmon-pond-0870a1e00.2.azurestaticapps.net/\u003e.\n\nIllustrates different scenarios related to [CORS][cors]:\n\n- A preflight request with the server responding without any `CORS` headers\n- A preflight request with the server responding with all the expected `CORS` headers with the exception of `Access-Control-Max-Age`\n- Preflight requests with the server responding with all the expected `CORS` headers including `Access-Control-Max-Age`\n  - Use a different path and query string to demonstrate the impact on the cache\n\n:rotating_light: ensure that _Disable cache_ is unchecked in the Network Developer Tools, otherwise the preflight requests will not be cached.\n\n## Without any CORS headers\n\n### Preflight request for NoCors\n\n- URL: `https://cors-func.azurewebsites.net/no-cors`\n- Method: `OPTIONS`\n\n**Relevant preflight request headers**:\n\n```text\naccess-control-request-headers: authorization\naccess-control-request-method: GET\norigin: https://salmon-pond-0870a1e00.2.azurestaticapps.net\n```\n\n**Relevant preflight response headers**:\n\nNone\n\n### Preflight result for NoCors\n\nThe preflight fails as the response does not contain a `Access-Control-Allow-Origin` header. See the output of the `Chrome` console below:\n\n```text\nAccess to XMLHttpRequest at 'https://cors-func.azurewebsites.net/no-cors' from origin 'https://salmon-pond-0870a1e00.2.azurestaticapps.net' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n```\n\n## With CORS headers (but without Access-Control-Max-Age)\n\n### Preflight request for CorsNoCache\n\n- URL: `https://cors-func.azurewebsites.net/cors-no-cache`\n- Method: `OPTIONS`\n\n**Relevant preflight request headers**:\n\n```text\naccess-control-request-headers: authorization\naccess-control-request-method: GET\norigin: https://salmon-pond-0870a1e00.2.azurestaticapps.net\n```\n\n**Relevant preflight response headers**:\n\n```text\naccess-control-allow-credentials: true\naccess-control-allow-headers: authorization\naccess-control-allow-method: GET\naccess-control-allow-origin: https://salmon-pond-0870a1e00.2.azurestaticapps.net\n```\n\n### Preflight result for CorsNoCache\n\nThe preflight succeeds and `Chrome` then issue the `GET` request.\n\n### GET request for CorsNoCache\n\n- URL: `https://cors-func.azurewebsites.net/cors-no-cache`\n- Method: `GET`\n\n**Relevant GET request headers**:\n\n```text\nauthorization: Bearer TopSecret\norigin: https://salmon-pond-0870a1e00.2.azurestaticapps.net\n```\n\n**Relevant GET response headers**:\n\n```text\naccess-control-allow-origin: https://salmon-pond-0870a1e00.2.azurestaticapps.net\n```\n\n### GET result for CorsNoCache\n\nThe `GET` succeeds and returns the content of the `Authorization` header (super secure I know):\n\n```json\n{\"authorization\":\"Bearer TopSecret\"}\n```\n\n**Note**: each subsequent `GET` call requires a preflight request:\n\n![One preflight per GET](./docs/img/many-preflights.png)\n\n## With CORS headers (and with Access-Control-Max-Age)\n\n### Preflight request for CorsCache\n\n- URL: `https://cors-func.azurewebsites.net/cors-cache`\n- Method: `OPTIONS`\n\n**Relevant preflight request headers**:\n\n```text\naccess-control-request-headers: authorization\naccess-control-request-method: GET\norigin: https://salmon-pond-0870a1e00.2.azurestaticapps.net\n```\n\n**Relevant preflight response headers**:\n\n```text\naccess-control-allow-credentials: true\naccess-control-allow-headers: authorization\naccess-control-allow-method: GET\naccess-control-allow-origin: https://salmon-pond-0870a1e00.2.azurestaticapps.net\naccess-control-max-age: 600\n```\n\n### Preflight result for CorsCache\n\nThe preflight succeeds and `Chrome` then issue the `GET` request.\n\n### GET request for CorsCache\n\n- URL: `https://cors-func.azurewebsites.net/cors-cache`\n- Method: `GET`\n\n**Relevant GET request headers**:\n\n```text\nauthorization: Bearer TopSecret\norigin: https://salmon-pond-0870a1e00.2.azurestaticapps.net\n```\n\n**Relevant GET response headers**:\n\n```text\naccess-control-allow-origin: https://salmon-pond-0870a1e00.2.azurestaticapps.net\n```\n\n### GET result for CorsCache\n\nThe `GET` succeeds and returns the content of the `Authorization` header (super secure I know):\n\n```json\n{\"authorization\":\"Bearer TopSecret\"}\n```\n\n**Note**: subsequent `GET` calls do not issue preflight requests:\n\n![Single preflight](./docs/img/single-preflight.png)\n\nThis is true as long as the result of the initial preflight is cached. `Access-Control-Max-Age` is capped by a [maximum value for each browser][max-age]:\n\n- 24 hours for Firefox\n- 2 hours for Chromium (10 minutes for v75 and prior)\n\nThe initial preflight is only cached for the same path and query string.\n\n[cors]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS\n[max-age]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age#Directives\n[github-actions-shield]: https://github.com/gabrielweyer/cors/actions/workflows/workflow.yml/badge.svg\n[github-actions]: https://github.com/gabrielweyer/cors/actions/workflows/workflow.yml\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabrielweyer%2Fcors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgabrielweyer%2Fcors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabrielweyer%2Fcors/lists"}