How HTTP Works

Request header

> Referer: https://example.com/page

Referer Header: What It Sends and How to Control It

Referer tells a server which page a request came from. What browsers send under the default strict-origin-when-cross-origin policy, and how to trim it.

Reviewed 5 min readbeginner2 sourcesTry itMarkdown
Direction
Request
Category
Navigation
Spec
RFC 9110 §10.1.3
JS can set it
No: forbidden header name
Note
Misspelled in the spec; the misspelling is the header name
On this page

TL;DR: Referer (yes, misspelled) is the request header that tells a server which page the request came from. Under the browser default, same-origin requests get the full URL, cross-origin HTTPS requests get only the origin (https://blog.example.com/), and HTTPS-to-HTTP requests get nothing. Use it for analytics and as a CSRF signal; it’s easy to fake and often missing, so never use it for authentication.

What is Referer?

Browsers attach Referer to navigations and resource loads to say where the request came from. The header keeps its historical misspelling; Referrer-Policy is spelled correctly. The “referrer” isn’t always the previous page: when a document loads an image or calls fetch, that document is the referrer. RFC 9110 section 10.1.3 defines the field.

How Referer Works

Say a reader is on https://blog.example.com/posts/caching?edition=web#examples, and the page uses the default strict-origin-when-cross-origin policy. Clicking a link to https://shop.example.com/products sends (examples on this page are trimmed):

GET /products HTTP/1.1
Host: shop.example.com
Referer: https://blog.example.com/

The shop only learns the origin. A link to another page on the blog itself would carry the path and query too. The fragment (#examples) is never sent.

Referer Format

Here’s what a same-origin request from that page carries:

Referer: https://blog.example.com/posts/caching?edition=web

Browsers always strip the fragment and any user:password@ part. Depending on the policy, they may also cut the value down to the origin with a trailing /, or drop the header entirely. MDN lists which URL parts are allowed.

When Browsers Send Referer

Links, form submissions, images and fetches all carry it, subject to policy. Typing a URL or opening a bookmark usually means there’s no referring page, so no header. A no-referrer policy or a link with rel="noreferrer" suppresses it. Under the default policy, going from HTTPS to HTTP drops it, but a page that sets unsafe-url sends the full URL even then.

To change the policy for one image without touching the rest of the page, set it on the element:

<img src="https://images.example.com/logo.png"
  referrerpolicy="no-referrer" alt="Logo">

The image server still sees the URL being requested and the client’s IP address. Referrer policy only controls what the request says about the page it came from.

Real-World Examples

A same-origin request from your cart page to checkout carries the cart path. A referral from another HTTPS site usually carries only that site’s origin. That includes search engines, so plan your analytics without their full query URLs or any particular vendor’s referral format.

Here’s a checkout request from https://shop.example.com/cart?coupon=SPRING under the default policy:

GET /checkout HTTP/1.1
Host: shop.example.com
Referer: https://shop.example.com/cart?coupon=SPRING

Source and destination share an origin, so checkout sees the cart’s query string. Move checkout to https://pay.example.com and it gets only the origin, even though both belong to the same company. Same-site isn’t same-origin.

Server-Side Usage

Parse the value before you compare it. This helper returns an HTTP(S) origin, or null:

function referralOrigin(value) {
  if (typeof value !== 'string') return null
  try {
    const url = new URL(value)
    return ['http:', 'https:'].includes(url.protocol) ? url.origin : null
  } catch {
    return null
  }
}

Compare the result against a configured public origin such as https://app.example.com, not against a substring of req.headers.host. Treat it as context; it’s not a login check.

In an existing Express app, the helper can label each request’s referral without keeping the full URL:

app.use((req, res, next) => {
  const origin = referralOrigin(req.get('Referer'))
  res.locals.referral = origin === null ? 'unknown'
    : origin === 'https://shop.example.com' ? 'internal' : 'external'
  res.locals.referralOrigin = origin
  next()
})

Define “internal” with a configured origin; the incoming Host header is under the client’s control. Use the label for reporting, and let checkouts with an unknown referral through, because plenty of legitimate ones arrive that way. Clients outside the browser can send any value they like.

Privacy and Security

URLs often contain account IDs or password-reset tokens, and Referer can leak them to third parties. On sensitive pages, set the policy in the document before it makes any requests:

<meta name="referrer" content="no-referrer">

For a single external link:

<a href="https://partner.example.com/" rel="noreferrer">Partner</a>

Common Referer Policies

The default is strict-origin-when-cross-origin: the full (stripped) URL for same-origin requests, the origin for cross-origin requests at the same security level, and nothing when going from HTTPS to HTTP. no-referrer sends nothing anywhere. origin drops the path and query everywhere, but sends the origin even from HTTPS to HTTP. MDN compares all directives.

Analytics Use Cases

Log a missing or unparseable value as “unknown”. Calling it “direct” lumps typed URLs together with policy suppression and privacy tools. If you only need the referring origin, store only the origin.

For attribution you control, put a campaign parameter on the destination link:

<a href="https://shop.example.com/products?campaign=partner-newsletter">
  View products
</a>

The parameter is part of the destination URL, so it survives no-referrer and shows up in your logs whether or not a Referer was sent. Anyone can type it, though, so treat it as untrusted reporting data rather than evidence the visit came from the partner.

Security Considerations

A prefix check like referer.startsWith('https://app.example.com') also accepts https://app.example.com.attacker.example/. Parse both sides and compare origins exactly. OWASP lists Origin/Referer checks as one layer of CSRF defense, alongside an explicit decision about missing values and separate authentication.

Testing Referer Headers

curl -i https://app.example.com/checkout \
  --referer 'https://app.example.com/cart'

curl sends whatever value you give it and applies no referrer policy. To see real browser behavior, navigate from a served page and inspect the destination request in the Network panel. Note that document.referrer tells you how the current page was reached; it isn’t the Referer the page sends on its own outgoing requests.

Compare a request with a referral and one without:

curl -i https://app.example.com/checkout
curl -i https://app.example.com/checkout --referer 'https://other.example/'

Both should succeed; this also checks that your analytics code copes with a missing header. To test how the browser trims the value, load a source page with a query string, follow a link to a same-origin page and one to another HTTPS origin, and look at each destination request.

Getting Referer right

Browser scripts can’t set Referer directly. Fetch offers referrer and referrerPolicy options, within limits. To suppress the referral on one request, set the policy and then check the request that went out:

await fetch('/api/data', { referrerPolicy: 'no-referrer' })

Frequently asked questions

What is the Referer header?

Referer is a request header carrying the URL of the page or document that made the request. Depending on the referrer policy, you get the full URL (minus fragment and credentials), just the origin, or nothing.

Why is Referer spelled wrong?

The historical spelling Referer is retained in the HTTP field name. Referrer-Policy uses the correct spelling.

When is Referer not sent?

It is missing on typed URLs and bookmarks, under privacy controls, with a no-referrer policy, and on rel=noreferrer links. The default policy also drops it when an HTTPS page links to an HTTP one, though a policy such as unsafe-url sends it anyway.

Is Referer reliable for security?

Only as supporting context, never as authentication. Non-browser clients can send any value, legitimate requests often omit it, and any origin check has to compare parsed origins exactly rather than by prefix.

Sources

  1. MDN Web Docs: Refererdeveloper.mozilla.org
  2. RFC 9110: Refererrfc-editor.org

Keep going

Browse /search