Skip to content

Commit 4aaa26f

Browse files
authored
feat: Add HTTP header configurations to options (#379)
* add custom headers * Add test check for correct headers * Add test for custom headers * Add docs * Add Auth header test * Add freeFormObjectKeys for free form config objects * Merge freeFormObjectKeys instead of reassign * Update tests for merging and overwriting headers * Update docs
1 parent b147465 commit 4aaa26f

File tree

4 files changed

+46
-4
lines changed

4 files changed

+46
-4
lines changed

src/amplitude-client.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,9 @@ var _parseConfig = function _parseConfig(options, config) {
317317
return;
318318
}
319319

320+
// Add exception in headers
321+
const freeFormObjectKeys = new Set(['headers']);
322+
320323
// validates config value is defined, is the correct type, and some additional value sanity checks
321324
var parseValidateAndLoad = function parseValidateAndLoad(key) {
322325
if (!Object.prototype.hasOwnProperty.call(options, key)) {
@@ -342,7 +345,9 @@ var _parseConfig = function _parseConfig(options, config) {
342345
};
343346

344347
for (var key in config) {
345-
if (Object.prototype.hasOwnProperty.call(config, key)) {
348+
if (freeFormObjectKeys.has(key)) {
349+
options[key] = { ...options[key], ...config[key] };
350+
} else if (Object.prototype.hasOwnProperty.call(config, key)) {
346351
parseValidateAndLoad(key);
347352
}
348353
}
@@ -1520,7 +1525,7 @@ AmplitudeClient.prototype.sendEvents = function sendEvents() {
15201525
};
15211526

15221527
var scope = this;
1523-
new Request(url, data).send(function (status, response) {
1528+
new Request(url, data, this.options.headers).send(function (status, response) {
15241529
scope._sending = false;
15251530
try {
15261531
if (status === 200 && response === 'success') {

src/options.js

+4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import language from './language';
3939
* @property {string} [unsentKey=`amplitude_unsent`] - localStorage key that stores unsent events.
4040
* @property {string} [unsentIdentifyKey=`amplitude_unsent_identify`] - localStorage key that stores unsent identifies.
4141
* @property {number} [uploadBatchSize=`100`] - The maximum number of events to send to the server per request.
42+
* @property {Object} [headers=`{ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }`] - Headers attached to an event(s) upload network request. Custom header properties are merged with this object.
4243
*/
4344
export default {
4445
apiEndpoint: 'api.amplitude.com',
@@ -89,4 +90,7 @@ export default {
8990
unsentKey: 'amplitude_unsent',
9091
unsentIdentifyKey: 'amplitude_unsent_identify',
9192
uploadBatchSize: 100,
93+
headers: {
94+
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
95+
},
9296
};

src/xhr.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@ import queryString from 'query-string';
33
/*
44
* Simple AJAX request object
55
*/
6-
var Request = function (url, data) {
6+
var Request = function (url, data, headers) {
77
this.url = url;
88
this.data = data || {};
9+
this.headers = headers;
910
};
1011

12+
function setHeaders(xhr, headers) {
13+
for (const header in headers) {
14+
xhr.setRequestHeader(header, headers[header]);
15+
}
16+
}
17+
1118
Request.prototype.send = function (callback) {
1219
var isIE = window.XDomainRequest ? true : false;
1320
if (isIE) {
@@ -35,7 +42,7 @@ Request.prototype.send = function (callback) {
3542
callback(xhr.status, xhr.responseText);
3643
}
3744
};
38-
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
45+
setHeaders(xhr, this.headers);
3946
xhr.send(queryString.stringify(this.data));
4047
}
4148
//log('sent request to ' + this.url + ' with data ' + decodeURIComponent(queryString(this.data)));

test/amplitude-client.js

+26
Original file line numberDiff line numberDiff line change
@@ -1482,6 +1482,32 @@ describe('AmplitudeClient', function () {
14821482
assert.equal(server.requests[0].url, 'http://api.amplitude.com');
14831483
assert.equal(server.requests[0].method, 'POST');
14841484
assert.equal(server.requests[0].async, true);
1485+
assert.equal(
1486+
server.requests[0].requestHeaders['Content-Type'],
1487+
'application/x-www-form-urlencoded;charset=utf-8',
1488+
);
1489+
});
1490+
1491+
it('should send request with merged custom header values', function () {
1492+
amplitude.init(apiKey, null, {
1493+
headers: { Authorization: 'Bearer NOT_A_REAL_BEARER_TOKEN' },
1494+
});
1495+
amplitude.logEvent('Event Type 1');
1496+
assert.lengthOf(server.requests, 1);
1497+
assert.equal(
1498+
server.requests[0].requestHeaders['Content-Type'],
1499+
'application/x-www-form-urlencoded;charset=utf-8',
1500+
);
1501+
assert.equal(server.requests[0].requestHeaders['Authorization'], 'Bearer NOT_A_REAL_BEARER_TOKEN');
1502+
});
1503+
1504+
it('should send request with overwritten custom header values', function () {
1505+
amplitude.init(apiKey, null, {
1506+
headers: { 'Content-Type': 'application/json;charset=utf-8' },
1507+
});
1508+
amplitude.logEvent('Event Type 1');
1509+
assert.lengthOf(server.requests, 1);
1510+
assert.equal(server.requests[0].requestHeaders['Content-Type'], 'application/json;charset=utf-8');
14851511
});
14861512

14871513
it('should send https request', function () {

0 commit comments

Comments
 (0)