Using XMLHttpRequest to Invoke ServiceNow REST APIs - ben-vargas/servicenow-wiki GitHub Wiki

XMLHttpRequest (XHR) is a built-in browser API that allows for making HTTP requests to servers. In a ServiceNow context, you can use XHR from client-side scripts (such as UI Pages or certain forms in the classic UI) to interact with the platform’s REST APIs. This is similar to using jQuery.ajax() or the newer fetch() API, but XMLHttpRequest is more traditional and requires some additional boilerplate code.


Prerequisites and Considerations

  1. Authentication:
    The example uses the X-UserToken header set to window.g_ck, a user token available in classic UI contexts that grants the currently logged-in user’s permissions.

    • Ensure you are running this code in a context where window.g_ck is defined (e.g., UI Page, classic form view).
    • If you are using ServiceNow UI pages, window.g_ck should be available for authenticated users.
  2. Permissions & Roles:
    Make sure the logged-in user has permission to perform the requested action (in this case, creating an incident). The Table API enforces ACLs and roles, so your user must have the necessary permissions.

  3. REST Endpoint:
    The code targets the /api/now/table/incident endpoint. Ensure this endpoint is correct for your use case. If you’re creating a different type of record, change the table name accordingly.

  4. Modern Alternatives:
    While XMLHttpRequest is fully supported, you may consider using fetch() or jQuery.ajax() as they can be more concise and offer additional convenience. However, XMLHttpRequest remains a valid and reliable approach.


Example Code

function tptest() {
    var xhr = new XMLHttpRequest();

    // Configure the POST request to the incident table
    xhr.open("POST", "/api/now/table/incident", true); // true = asynchronous request
    xhr.setRequestHeader('Accept', 'application/json');
    xhr.setRequestHeader('Content-Type', 'application/json');

    // Authorization: Using X-UserToken for an authenticated session
    xhr.setRequestHeader('X-UserToken', window.g_ck);

    // Handle the state changes of the XHR object
    xhr.onreadystatechange = function() {
        // Use === to compare, and XMLHttpRequest.DONE for clarity
        if (this.readyState === XMLHttpRequest.DONE) {
            console.log('status: ' + this.status);

            // The response is typically a JSON string; verify it's a proper JSON response
            console.log('response: ' + this.response);
            console.log('typeof: ' + typeof this.response);

            // If you want to parse JSON:
            try {
                var parsedResponse = JSON.parse(this.response);
                console.log('Parsed short_description:', parsedResponse.result.short_description);
            } catch (e) {
                console.error('Failed to parse JSON response:', e);
            }
        }
    };

    // Data to send with the POST request
    var data = {
        short_description: "some test data here...",
        impact: 1
    };

    // Convert the JavaScript object to a JSON string
    xhr.send(JSON.stringify(data));
}

Key Points in the Code Above:

  • Method & Headers:
    POST method for creating a new record.
    Content-Type: application/json and Accept: application/json to ensure correct data formats.

  • X-UserToken:
    Using X-UserToken with window.g_ck to authenticate as the current user. This relies on a valid session and may not work in non-authenticated contexts.

  • Response Handling:
    Checks readyState against XMLHttpRequest.DONE (constant value 4).
    Logs status and response. Attempts to parse JSON for structured data access. Wrap JSON parsing in a try/catch block to handle malformed responses gracefully.

  • Data Sending:
    Uses JSON.stringify() to send a JSON payload to create the incident.


Best Practices

  1. Check readyState Properly:
    Ensure you use a strict equality check (===) and compare against XMLHttpRequest.DONE (or 4) rather than using assignment (=).

  2. Validate Responses:
    Responses should be checked to ensure they contain a valid result field before accessing attributes.

  3. Error Handling:
    Implement error handling for unexpected responses. Consider what should happen if this.status indicates a non-2xx status code.

  4. Security & Permissions:
    Relying on window.g_ck means you’re using the currently authenticated user’s session. Ensure this meets your security requirements. For non-authenticated scenarios or external integrations, use Basic Auth or OAuth tokens as needed.


Additional Resources


Conclusion

Using XMLHttpRequest in ServiceNow to interact with REST APIs is still valid and supported. With proper authentication headers, JSON formatting, and careful handling of the request/response cycle, you can seamlessly create and manipulate records. While newer APIs like fetch() provide a more modern approach, XMLHttpRequest remains a reliable choice, especially in legacy codebases or for developers familiar with its patterns.