diff --git a/packages/opentelemetry-exporter-collector/src/platform/browser/util.ts b/packages/opentelemetry-exporter-collector/src/platform/browser/util.ts index a695ee6944..f085d7ae6a 100644 --- a/packages/opentelemetry-exporter-collector/src/platform/browser/util.ts +++ b/packages/opentelemetry-exporter-collector/src/platform/browser/util.ts @@ -55,8 +55,11 @@ export function sendWithXhr( ) { const xhr = new XMLHttpRequest(); xhr.open('POST', url); - xhr.setRequestHeader('Accept', 'application/json'); - xhr.setRequestHeader('Content-Type', 'application/json'); + + if (!Object.keys(headers).includes('Accept')) + xhr.setRequestHeader('Accept', 'application/json'); + if (!Object.keys(headers).includes('Content-Type')) + xhr.setRequestHeader('Content-Type', 'application/json'); Object.entries(headers).forEach(([k, v]) => { xhr.setRequestHeader(k, v); }); diff --git a/packages/opentelemetry-exporter-collector/test/browser/util.test.ts b/packages/opentelemetry-exporter-collector/test/browser/util.test.ts new file mode 100644 index 0000000000..1e383613da --- /dev/null +++ b/packages/opentelemetry-exporter-collector/test/browser/util.test.ts @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as sinon from 'sinon'; +import { sendWithXhr } from "../../src/platform/browser/util"; +import { + ensureHeadersContain, +} from '../helper'; + + +describe('util - browser', () => { + + describe('when Content-Type and Accept headers are set explicit', () => { + let server: any; + + const explicitContentTypeAndAcceptHeaders = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }; + const body = ""; + const url = ""; + + let onSuccessStub: sinon.SinonStub; + let onErrorStub: sinon.SinonStub; + + beforeEach(() => { + onSuccessStub = sinon.stub(); + onErrorStub = sinon.stub(); + server = sinon.fakeServer.create(); + }); + afterEach(() => { + server.restore(); + sinon.restore(); + }); + + it('should successfully use XMLHttpRequest and Request Headers contain the expilicit defined Content-Type and Accept Header Values', done => { + sendWithXhr(body, url, explicitContentTypeAndAcceptHeaders, onSuccessStub, onErrorStub) + + // ;charset=utf-8 is applied by sinon.fakeServer + const expectedHeaders = { ...explicitContentTypeAndAcceptHeaders, "Content-Type": "application/json;charset=utf-8" } + + setTimeout(() => { + const { requestHeaders } = server.requests[0]; + ensureHeadersContain(requestHeaders, expectedHeaders); + done(); + }); + }); + }); +}); +