Describe the bug
Product: rum.
Same-origin XHR/fetch resource events are missing _dd.trace_id, _dd.span_id, method and status_code whenever the app uses a <base href> that differs from the current path and issues document-relative request URLs (e.g. api/foo instead of /api/foo). The backend span is created fine and the request carries traceparent, but the RUM resource never links to it, so @type:resource @_dd.trace_id:* comes back empty and RUM ↔ APM correlation is broken.
The cause is in normalizeUrl (packages/js-core/src/util/urlPolyfill.ts), which records the request URL for XHR/fetch resources:
export function normalizeUrl(url: string) {
return buildUrl(url, globalObject.location?.href).href
}
It resolves relative URLs against location.href, but the browser resolves relative request URLs against the document base URI (<base href>). So the URL recorded for the resource doesn't match the PerformanceResourceTiming.name the browser actually requested, and getMatchingRequest never pairs them. traceparent is still injected because allowedTracingUrls matches on origin, which the mis-resolved URL keeps — which is why it looks like propagation works until you check the RUM side.
With <base href="/"> on route /deep/route, a request to api/foo:
|
URL |
Actual request / PerformanceResourceTiming.name |
https://host/api/foo |
Recorded by normalizeUrl (base https://host/deep/route) |
https://host/deep/api/foo |
To Reproduce
- Serve a SPA at
/ with <base href="/"> and init RUM with allowedTracingUrls: [window.location.origin] and trackResources: true.
- Navigate to a route deeper than the base, e.g.
/deep/route.
- Issue a document-relative request:
new XMLHttpRequest().open('GET', 'api/foo') or fetch('api/foo').
- Check the resulting resource event.
The request carries traceparent, but the resource event has no _dd.trace_id, _dd.span_id, method or status_code. Switching the app to a root-relative URL (/api/foo) makes all four appear, since root-relative URLs are base-independent.
Seen on @datadog/browser-rum 7.7.0 in Chrome. In production this was 0 of ~13,600 same-origin XHR resource events carrying a trace id over 24h; cross-origin (absolute URL) requests were fine.
Expected behavior
The resource event for a document-relative request should match its PerformanceResourceTiming entry and carry method, status_code, _dd.trace_id and _dd.span_id, the same as it does for root-relative requests.
Describe the bug
Product:
rum.Same-origin XHR/fetch resource events are missing
_dd.trace_id,_dd.span_id,methodandstatus_codewhenever the app uses a<base href>that differs from the current path and issues document-relative request URLs (e.g.api/fooinstead of/api/foo). The backend span is created fine and the request carriestraceparent, but the RUM resource never links to it, so@type:resource @_dd.trace_id:*comes back empty and RUM ↔ APM correlation is broken.The cause is in
normalizeUrl(packages/js-core/src/util/urlPolyfill.ts), which records the request URL for XHR/fetch resources:It resolves relative URLs against
location.href, but the browser resolves relative request URLs against the document base URI (<base href>). So the URL recorded for the resource doesn't match thePerformanceResourceTiming.namethe browser actually requested, andgetMatchingRequestnever pairs them.traceparentis still injected becauseallowedTracingUrlsmatches on origin, which the mis-resolved URL keeps — which is why it looks like propagation works until you check the RUM side.With
<base href="/">on route/deep/route, a request toapi/foo:PerformanceResourceTiming.namehttps://host/api/foonormalizeUrl(basehttps://host/deep/route)https://host/deep/api/fooTo Reproduce
/with<base href="/">and init RUM withallowedTracingUrls: [window.location.origin]andtrackResources: true./deep/route.new XMLHttpRequest().open('GET', 'api/foo')orfetch('api/foo').The request carries
traceparent, but the resource event has no_dd.trace_id,_dd.span_id,methodorstatus_code. Switching the app to a root-relative URL (/api/foo) makes all four appear, since root-relative URLs are base-independent.Seen on
@datadog/browser-rum7.7.0 in Chrome. In production this was 0 of ~13,600 same-origin XHR resource events carrying a trace id over 24h; cross-origin (absolute URL) requests were fine.Expected behavior
The resource event for a document-relative request should match its
PerformanceResourceTimingentry and carrymethod,status_code,_dd.trace_idand_dd.span_id, the same as it does for root-relative requests.