how to test my servlet via Javascript in localhost? | Community
Skip to main content
jayv25585659
Level 8
October 27, 2025
Question

how to test my servlet via Javascript in localhost?

  • October 27, 2025
  • 4 replies
  • 315 views

So in postman, I am sending using this header

 

 

and this is working fine. (YW string is admin:admin encoded using base64).

 

I'm trying to do the same in javascript, but I keep on getting a 403.

headers.append('Content-Type', 'application/json');
if (window.location.host.indexOf('localhost') != -1) {
headers.append('Authorization', 'Basic YWRtaW46YWRtaW4=');
}
const response = await fetch(myUrl,
{
method: 'POST',
headers: headers,
body: payload
}
);


Any ideas on how it can be done? Thanks

4 replies

Heena_Shirke
Level 2
October 27, 2025

Hi @jayv25585659, you can try configuring "Adobe Granite Cross-Origin Resource Sharing Policy" configuration to allow the domain from where JS calls occur.

SantoshSai
Community Advisor
Community Advisor
October 27, 2025

Hi @jayv25585659,

Here’s what’s actually happening - Postman works because it’s not affected by browser security rules. But when you call your AEM servlet via JavaScript in a web page:

Basic Auth header is correct
Browser blocks the request -> 403 due to CORS / CSRF / Sling Referrer Filter

 

Add these headers:

const headers = new Headers();
headers.append("Content-Type", "application/json");
headers.append("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin
headers.append("CSRF-Token", "nocheck"); // Important for POST in Author

Then:

const response = await fetch("http://localhost:4502/bin/acara/principals/accessrequest", {
  method: "POST",
  credentials: "include",
  headers: headers,
  body: JSON.stringify(payload)
});

For AEM Author only

You also need to whitelist your local site:

AEM -> Web Console ->

OSGi Config -> Adobe Granite Cross-Origin Resource Sharing Policy
Add:

Allowed Origins: http://localhost:3000 (or your front-end port)
Allowed Headers: Authorization, Content-Type, CSRF-Token
Supported Methods: POST, GET, OPTIONS

Also update:

Adobe Granite Referrer Filter
-> Add localhost to allow list

Quick Test to Confirm Your Servlet Works in Browser

Open browser DevTools:

fetch("http://localhost:4502/bin/acara/principals/accessrequest", {
    method: "POST",
    headers: {
        "Authorization": "Basic YWRtaW46YWRtaW4=",
        "Content-Type": "application/json",
        "CSRF-Token": "nocheck"
    },
    body: JSON.stringify({ test: true })
}).then(r => console.log(r.status, r.text()));

If this works -> CORS/Referrer are the missing pieces in your frontend app.

Santosh Sai
ManviSharma
Adobe Employee
Adobe Employee
October 27, 2025

 

Hi @jayv25585659 ,

This is a classic browser vs Postman issue. Postman skips browser security (no preflight/CORS and no enforced CSRF), so a request that works there can get 403 from the browser. Two things to check/fix:

1) CORS / preflight

  • Open DevTools → Network and look for the OPTIONS request (preflight).

  • If OPTIONS returns 4xx or is missing Access-Control-Allow-* headers, configure AEM to allow the origin, Authorization, Content-Type, CSRF-Token and the POST method.

  • Browser requires server to reply with these headers for the real POST to be allowed.

2) AEM CSRF protection (very common cause)

  • AEM often requires a CSRF token on POSTs. Postman may work without it; the browser will not.

  • Fetch the token and send it in CSRF-Token header before your POST.

Minimal flow (works cross-origin if CORS is allowed):

 

// Step 1: Fetch CSRF token
const getCsrfToken = async () => {
const response = await fetch('http://localhost:4502/libs/granite/csrf/token.json', {
credentials: 'include',
});

if (!response.ok) {
throw new Error(`Failed to fetch CSRF token: ${response.statusText}`);
}

const data = await response.json();
return data.token;
};

// Step 2: Send POST request with Basic Auth and CSRF token
const sendAccessRequest = async (payload) => {
const token = await getCsrfToken();

const response = await fetch('http://localhost:4502/bin/acara/principals/accessrequest.json', {
method: 'POST',
mode: 'cors', // required for cross-origin requests
credentials: 'include', // include cookies/session
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic YWRtaW46YWRtaW4=',
'CSRF-Token': token,
},
body: JSON.stringify(payload),
});

if (!response.ok) {
throw new Error(`Request failed: ${response.status} ${response.statusText}`);
}

return response.json();
};

// Example usage
try {
const payload = { /* your request body */ };
const result = await sendAccessRequest(payload);
console.log('Access request successful:', result);
} catch (error) {
console.error('Error:', error);
}

Hope this helps.

Regards,
Manvi Sharma

lavishvasuja
Level 3
October 31, 2025

Hi @jayv25585659 ,

Here’s a quick way to make a POST request to your AEM endpoint using a pre-encoded Basic Auth token and a local CSRF bypass for testing.

const headers = new Headers({ 'Content-Type': 'application/json', 'Authorization': 'Basic YWRtaW46YWRtaW4=', // pre-encoded token 'CSRF-Token': 'nocheck' // for local testing }); const res = await fetch('http://localhost:4502/bin/your/servlet/endpoint', { method: 'POST', headers, credentials: 'include', body: JSON.stringify(payload) });

 

 Notes:
 Make sure payload is JSON.stringified.
credentials: 'include' sends cookies/session.
For production, replace 'nocheck' with a real CSRF token.

Thanks,

Lavish Vasuja