Skip to content

Commit

Permalink
Merge pull request #34 from JalexSocial/mat-corspolicy-builder-extension
Browse files Browse the repository at this point in the history
Htmx.Net doesn't work in a cross origin context without a CORS policy (Fixes #33)
  • Loading branch information
khalidabuhakmeh authored Oct 4, 2023
2 parents 05faa28 + 305fdb8 commit 95d2764
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
42 changes: 42 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@ Request.IsHtmx(out var values);

Read more about the other header values on the [official documentation page](https://htmx.org/reference/#request_headers).

#### Browser Caching

As a special note, please be mindful that if your server can render different content for the same URL depending on some other headers, you need to use the Vary response HTTP header. For example, if your server renders the full HTML when Request.IsHtmx() is false, and it renders a fragment of that HTML when Request.IsHtmx() is true, you need to add Vary: HX-Request. That causes the cache to be keyed based on a composite of the response URL and the HX-Request request header — rather than being based just on the response URL.

```c#
// in a Razor Page
if (Request.IsHtmx())
{
Response.Headers.Add("Vary", "HX-Request");
return Partial("_Form", this)
}

return Page();
```


### HttpResponse

We can set Http Response headers using the `Htmx` extension method, which passes an action and `HtmxResponseHeaders` object.
Expand All @@ -64,6 +80,32 @@ Response.Htmx(h => {
});
```

#### CORS Policy

By default, all Htmx requests and responses will be blocked in a cross-origin context.

If you configure your application in a cross-origin context, then setting a CORS policy in ASP.NET Core also allows you to define specific restrictions on request and response headers,
enabling fine-grained control over the data that can be exchanged between your web application and different origins.

This library provides a simple approach to exposing Htmx headers to your CORS policy:

```c#
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins("http://example.com", "http://www.contoso.com")
.WithHeaders(HtmxRequestHeaders.Keys.All) // Add htmx request headers
.WithExposedHeaders(HtmxResponseHeaders.Keys.All) // Add htmx response headers
});
});
```

## Htmx.TagHelpers

### Getting Started
Expand Down
5 changes: 5 additions & 0 deletions src/Htmx/HtmxRequestHeaders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public static class Keys
public const string TriggerName = "HX-Trigger-Name";
public const string Trigger = "HX-Trigger";
public const string Boosted = "HX-Boosted";

public static string[] All { get; } = new[]
{
CurrentUrl, HistoryRestoreRequest, Prompt, Request, Target, TriggerName, Trigger, Boosted
};
}

public HtmxRequestHeaders(HttpRequest request)
Expand Down
5 changes: 5 additions & 0 deletions src/Htmx/HtmxResponseHeaders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public static class Keys
public const string Reswap = "HX-Reswap";
public const string Retarget = "HX-Retarget";
public const string ReplaceUrl = "HX-Replace-Url";

public static string[] All { get; } = new[]
{
PushUrl, Location, Redirect, Refresh, Trigger, TriggerAfterSettle, TriggerAfterSwap, Reswap, Retarget, ReplaceUrl
};
}

internal HtmxResponseHeaders(IHeaderDictionary headers)
Expand Down

0 comments on commit 95d2764

Please sign in to comment.