diff --git a/README.md b/README.md index 999f0025..a46d6b19 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ [![CircleCI](https://circleci.com/gh/treasure-data/td-js-sdk/tree/master.svg?style=svg)](https://circleci.com/gh/treasure-data/td-js-sdk/tree/master) -> :warning: NOTE: From version 3.1.0, we use our new JavaScript endpoint to log data, the `host` configuration -need to be changed to point to the new endpoint, see [Streaming Ingestion](STREAMING_INGESTION.md) for more information +> :warning: NOTE: In version 3.1, we support our new JavaScript endpoint to log data, however there are configurations need to be +changed in order to opt-in this feature, see [Streaming Ingestion](STREAMING_INGESTION.md) for more information # Table of Contents [Getting started](#getting-started) diff --git a/STREAMING_INGESTION.md b/STREAMING_INGESTION.md index a649a38b..c185c2a6 100644 --- a/STREAMING_INGESTION.md +++ b/STREAMING_INGESTION.md @@ -2,7 +2,10 @@ ## Configurations -We still use the same configurations, but the `host` configuration needs to be changed so that it will point to our new endpoint. +We introduce new option to opt-in our new JavaScript endpoint, named `useNewJavaScriptEndpoint`, which has value of `true` or `false`. +When you enable this option, you need to change the `host` configuration as well, so that it will point to our new endpoint + +:information_source: This new feature won't impact the server side cookie and the personalization features The `host` configuration will have the following values, depending on which environment you want to ingest data. @@ -24,6 +27,7 @@ Example: var foo = new Treasure({ database: 'foo', writeKey: 'your_write_only_key', + useNewJavaScriptEndpoint: true, host: 'us01.records.in.treasuredata.com' }); ``` diff --git a/bin/build.sh b/bin/build.sh index 53d543a3..2c55b73e 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -6,7 +6,7 @@ ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" VERSION=$(cat $ROOT_DIR/package.json | jq -r '.version') HOST='in.treasuredata.com' DATABASE="" -PATHNAME="/" +PATHNAME="/js/v3/event/" GLOBAL="Treasure" FILENAME="td" TO_VERSION=$(echo $VERSION | sed 's/\.[-a-zA-Z0-9]*$//g') diff --git a/lib/config.js b/lib/config.js index 2ca29157..89b68625 100644 --- a/lib/config.js +++ b/lib/config.js @@ -3,5 +3,5 @@ module.exports = { VERSION: '3.1.0', HOST: 'in.treasuredata.com', DATABASE: '', - PATHNAME: '/' + PATHNAME: '/js/v3/event/' } diff --git a/lib/configurator.js b/lib/configurator.js index be07d886..733377f2 100644 --- a/lib/configurator.js +++ b/lib/configurator.js @@ -45,6 +45,7 @@ var defaultSSCCookieDomain = function () { exports.DEFAULT_CONFIG = { database: config.DATABASE, development: false, + useNewJavaScriptEndpoint: false, globalIdCookie: '_td_global', host: config.HOST, logging: true, @@ -86,6 +87,10 @@ exports.configure = function configure (options) { validateOptions(this.client) + if (this.client.useNewJavaScriptEndpoint) { + this.client.pathname = '/' + } + if (!this.client.endpoint) { this.client.endpoint = 'https://' + this.client.host + this.client.pathname } diff --git a/lib/plugins/globalid.js b/lib/plugins/globalid.js index f3d5be9c..13f56aec 100644 --- a/lib/plugins/globalid.js +++ b/lib/plugins/globalid.js @@ -77,6 +77,10 @@ function fetchGlobalID (success, error, forceFetch, options) { if (!this.inSignedMode()) { return error('not in signed in mode') } + + if (!this.isGlobalIdEnabled()) { + return error('global id is not enabled') + } var cookieName = this.client.globalIdCookie var cachedGlobalId = cookie.getItem(cookieName) if (cachedGlobalId && !forceFetch) { @@ -89,17 +93,24 @@ function fetchGlobalID (success, error, forceFetch, options) { options.sameSite = 'None' } - var url = 'https://' + this.client.host + var url = 'https://' + this.client.host + '/js/v3/enable_global_id' + var requestHeaders = {} + var ignoreDefaultHeaders = false + + if (this.client.useNewJavaScriptEndpoint) { + url = 'https://' + this.client.host + + requestHeaders['Authorization'] = 'TD1 ' + this.client.writeKey + requestHeaders['User-Agent'] = navigator.userAgent + requestHeaders['Content-Type'] = misc.globalIdAdlHeaders['Content-Type'] + requestHeaders['Accept'] = misc.globalIdAdlHeaders['Accept'] + ignoreDefaultHeaders = true + } api.get(url, { - headers: { - 'Authorization': 'TD1 ' + this.client.writeKey, - 'User-Agent': navigator.userAgent, - 'Content-Type': misc.globalIdContentTypeHeader, - 'Accept': misc.globalIdAcceptHeader - - } + headers: requestHeaders, + ignoreDefaultHeaders: ignoreDefaultHeaders }) .then(function (res) { var cachedId = cacheSuccess(res, cookieName, options) diff --git a/lib/record.js b/lib/record.js index f308a5f6..3415f2ba 100644 --- a/lib/record.js +++ b/lib/record.js @@ -192,29 +192,44 @@ exports._sendRecord = function _sendRecord (request, success, error, blockedEven var url = request.url + '?' + params.join('&') var isClickedLink = request.record.tag === 'a' && !!request.record.href - var authHeader = { - 'Authorization': 'TD1 ' + request.apikey, - 'User-Agent': navigator.userAgent - } - - if (this.isGlobalIdEnabled()) { - authHeader['Content-Type'] = misc.globalIdContentTypeHeader - authHeader['Accept'] = misc.globalIdAcceptHeader + var requestHeaders = {} + var payload + var ignoreDefaultHeaders = false + + if (this.client.useNewJavaScriptEndpoint) { + requestHeaders['Authorization'] = 'TD1 ' + request.apikey + requestHeaders['User-Agent'] = navigator.userAgent + + if (this.isGlobalIdEnabled()) { + requestHeaders['Content-Type'] = misc.globalIdAdlHeaders['Content-Type'] + requestHeaders['Accept'] = misc.globalIdAdlHeaders['Accept'] + } else { + requestHeaders['Content-Type'] = misc.adlHeaders['Content-Type'] + requestHeaders['Accept'] = misc.adlHeaders['Accept'] + } + + ignoreDefaultHeaders = true + + payload = { + events: [request.record] + } + } else { + requestHeaders['X-TD-Write-Key'] = request.apikey + payload = JSON.stringify(request.record) } if (window.fetch && (this._windowBeingUnloaded || isClickedLink)) { api .postWithTimeout( url, - { - events: [request.record] - }, + payload, this.client.jsonpTimeout, { method: 'POST', keepalive: true, credentials: 'include', - headers: authHeader + ignoreDefaultHeaders: ignoreDefaultHeaders, + headers: requestHeaders } ) .then(success) @@ -223,11 +238,10 @@ exports._sendRecord = function _sendRecord (request, success, error, blockedEven api .post( url, + payload, { - events: [request.record] - }, - { - headers: authHeader + ignoreDefaultHeaders: ignoreDefaultHeaders, + headers: requestHeaders } ) .then(success) diff --git a/lib/utils/misc.js b/lib/utils/misc.js index d5c0dfa8..dc3c5f97 100644 --- a/lib/utils/misc.js +++ b/lib/utils/misc.js @@ -73,12 +73,22 @@ function camelCase (str) { }, '') } +var adlHeaders = { + 'Content-Type': 'application/vnd.treasuredata.v1+json', + 'Accept': 'application/vnd.treasuredata.v1+json' +} + +var globalIdAdlHeaders = { + 'Content-Type': 'application/vnd.treasuredata.v1.js+json', + 'Accept': 'application/vnd.treasuredata.v1.js+json' +} + module.exports = { disposable: disposable, invariant: invariant, fetchWithTimeout: fetchWithTimeout, camelCase: camelCase, isLocalStorageAccessible: isLocalStorageAccessible, - globalIdContentTypeHeader: 'application/vnd.treasuredata.v1.js+json', - globalIdAcceptHeader: 'application/vnd.treasuredata.v1.js+json' + adlHeaders: adlHeaders, + globalIdAdlHeaders: globalIdAdlHeaders } diff --git a/lib/utils/xhr.js b/lib/utils/xhr.js index 4c270125..5a486335 100644 --- a/lib/utils/xhr.js +++ b/lib/utils/xhr.js @@ -7,8 +7,8 @@ var OK_STATUS = 200 var NOT_MODIFIED = 304 var defaultHeaders = { - 'Content-Type': 'application/vnd.treasuredata.v1+json', - 'Accept': 'application/vnd.treasuredata.v1+json' + 'Content-Type': 'application/json', + 'X-TD-Fetch-Api': 'true' } var FETCH_CREDENTIALS = { @@ -149,6 +149,11 @@ function _timeout (milliseconds, promise, timeoutMessage) { function postWithTimeout (url, body, milliseconds, options) { if (window.AbortController) { var controller = new window.AbortController() + + var headers = getHeaders(options.headers, isDefaultHeadersIgnored(options)) + + options.headers = headers + var promise = window.fetch(url, Object.assign({}, options, {signal: controller.signal})) var timeoutId = setTimeout(function () { controller.abort()