SharePointVault ~/gotchas/spfx ⌕ Search 404 pages, error messages, scripts…Ctrl K ★ Star
M↓ README.mdM↓ webproxy-is-add-in-only.md
sharepoint-vault›gotchas›spfx›webproxy-is-add-in-only.mdhistoryedit on GitHub
● GOTCHAspfx· 2 min read

SP.WebProxy is add-in-only — from SPFx it 403s with "without an app context"

applies to: SharePoint Onlinereviewed: 2026-07-16#spfx#rest-api#cors#webproxy

SP.WebProxy is legacy add-in-only, so from SPFx it returns a fake HTTP 200 whose body is really a 403 — there is no SharePoint-native CORS proxy for SPFx, so make the target send the CORS header or fetch through your own backend.

SP.WebProxy patří jen do starého add-in modelu, takže ze SPFx vrátí falešnou HTTP 200, jejíž tělo je ve skutečnosti 403 – žádná nativní SharePoint CORS proxy pro SPFx neexistuje, takže ať cíl pošle CORS hlavičku, nebo načítej přes vlastní backend.

Symptom

You need to read a cross-origin page or API from an SPFx web part. The browser blocks the direct fetch (the target sends no Access-Control-Allow-Origin), so you reach for SharePoint's own server-side proxy:

POST /_api/SP.WebProxy.invoke
{"requestInfo":{"__metadata":{"type":"SP.WebRequestInfo"},"Url":"https://example.com","Method":"GET"}}

The call returns HTTP 200 — and yet you get no content. The real answer is buried in the response body:

{"d":{"Invoke":{"__metadata":{"type":"SP.WebResponseInfo"},
  "Body":"Calls to WebProxy without an app context are not allowed.",
  "Headers":{"results":[]},
  "StatusCode":403}}}

This happens even though you are signed in and passed a valid X-RequestDigest.

Cause

SP.WebProxy belongs to the legacy SharePoint Add-in model. It only serves callers running in an add-in context, where the remote host is declared up front in the add-in's AppManifest.xml:

<RemoteEndpoints>
  <RemoteEndpoint Url="https://example.com" />
</RemoteEndpoints>

SPFx web parts and extensions do not run in an add-in context — they are page-hosted script. There is no manifest in which to declare a remote endpoint, so the proxy refuses every call, regardless of permissions, digest, or site collection settings.

There is no SharePoint-native CORS proxy available to SPFx.

Fix

Pick one of these — in this order:

  1. Make the target allow you. If the URL is yours (your website, intranet, internal API), add the header on that side: Access-Control-Allow-Origin: https://contoso.sharepoint.com. Zero infrastructure, and it covers the common "read our own web properties" case.
  2. Fetch server-side from your own backend (Azure Function, or whatever you already run) and have SPFx call that. The only option that works for arbitrary third-party pages. If you do this, treat the endpoint as an SSRF target: allow http(s) only, block private ranges (10.x, 192.168.x, 127.x, 169.254.x, ::1) — re-check after every redirect — and cap response size and timeout.
  3. Public CORS proxies (allorigins, codetabs, corsproxy, r.jina.ai): they work until they don't, and every URL you request travels through a stranger's server. Fine for a public RSS demo; not fine for anything a customer would call confidential.

Notes

  • The 200-that-isn't trap: the outer HTTP status reports on the OData envelope, not on the proxied request. A naive if (res.ok) treats this failure as success. The real status lives at d.Invoke.StatusCode, and the error text at d.Invoke.Body — check those, not res.ok.
  • Don't confuse "we trust this URL" with CORS. An allowlist you configure says you trust the target. CORS is the target granting your origin permission to read it. Only the second one unblocks the browser, and only the target can grant it — no amount of configuration on your side substitutes for it.
  • Probe it yourself from any modern page on the site (F12 console): POST /_api/contextinfo for the digest, then POST SP.WebProxy.invoke as above and read d.Invoke.StatusCode.
Was this helpful?ask or add your experience on GitHub →
Saved you an hour? A star on GitHub helps other SharePoint people find the vault.★ Star on GitHub
last reviewed: 2026-07-16last updated: 2026-09-24historyedit on GitHubview source