Code Patterns
Endpoints built through object-oriented classes, DOM APIs, and framework-specific AJAX patterns. These test whether the analyzer understands how real-world JavaScript constructs HTTP requests.
ES6 class resolves this.baseURL
A class sets this.baseURL in the constructor and concatenates it in a method. The analyzer must track this inside class methods.
class NotificationService {
constructor() {
this.baseURL = "/api/notifications";
}
getUnread() {
return fetch(this.baseURL + "/unread");
}
}
Global variable with jQuery $.ajax()
A global variable holds the API prefix. jQuery's $.ajax() builds the request. Two functions, two endpoints.
var bookmarkApi = "/api/bookmarks";
function saveBookmark(data) {
$.ajax({
url: bookmarkApi + "/save",
method: "POST",
data: data
});
}
function removeBookmark(id) {
$.ajax({
url: bookmarkApi + "/remove",
method: "DELETE",
data: { id: id }
});
}
Prototype class, never instantiated
Old-style constructor function with prototype methods. this.baseURL is set in init(), used in track(). The class is never instantiated with new.
function AnalyticsClient() {}
AnalyticsClient.prototype.init = function () {
this.baseURL = '/api/analytics/';
};
AnalyticsClient.prototype.track = function (event, data) {
fetch(this.baseURL + 'track', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ event: event, data: data })
});
};
// Class defined but NEVER instantiated.
// No `new AnalyticsClient()` anywhere on the page.
XMLHttpRequest raw sink
xhr.open('POST', url) followed by xhr.send(data). The legacy browser API β no library, no wrapper. The analyzer must recognize XMLHttpRequest as an HTTP sink.
function sendBeacon(payload) {
var xhr = new XMLHttpRequest();
xhr.open("POST", "/api/telemetry/beacon");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(payload));
}
axios library sink
axios.get() with a global variable prefix. The analyzer must recognize the axios library as an HTTP sink alongside native fetch() and XMLHttpRequest.
const feedApi = "/api/feed";
const loadLatestFeed = async () => {
const res = await axios.get(feedApi + "/latest");
console.log(res.data);
};
window.location assignment
window.location = url β not a traditional AJAX call, but triggers a server request.
const downloadExport = (format) => {
const url = "/api/export/download";
window.location = url;
};
fetch() with encodeURIComponent()
A built-in browser function wraps a parameter inside the URL expression. The analyzer must evaluate through it.
const executeSearch = (query) => {
const url = "/api/search/query?q=" +
encodeURIComponent(query);
fetch(url);
};
Angular $http.post() sink
AngularJS $http service β a framework-specific HTTP client. The analyzer must recognize framework APIs as sinks, not just native browser functions.
var settingsApi = "/api/user/settings";
function saveUserSettings(prefs) {
$http.post(settingsApi + "/save", prefs);
}