When I use an expired PAT attempting to access the REST end-point, in the browser’s Dev Tools console window I will get:
GET https://dev.azure.com/contoso/_apis/connectionData net::ERR_FAILED 401 (Unauthorized)
But it is impossible to get the fact that there’s a 401 status code from inside JavaScript. I’ve tried fetch with “then” / “catch” / and await with try/catch. I’ve also tried XMLHttpRequest. The only error I get is:
TypeError: Failed to fetch
Since the browser is clearly seeing the 401 (Unauthorized)
, I’d like to be detect that status code.
The browser Dev Tools console also has the following:
Access to fetch at 'https://dev.azure.com/contoso/_apis/connectionData' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
The Network tab shows the 401 status as well:
Using no-cors
hides makes everything opaque, and you don’t get the 401 status.
Here’s a runnable sample:
<!DOCTYPE html>
<html>
<body>
<script>
(async function () {
"use strict";
const API_ORGANIZATION="contoso"
const expiredPat = 'ts44tplifj4hbbzeitcz5dg5az4q3mpqcxqmrxo4zwlgy3scobzq'
const pat = expiredPat
// Fetch data from Azure DevOps
async function ado(api) {
const url = `https://dev.azure.com/${API_ORGANIZATION}/_apis/${api}`
console.log(`url: ${url}`)
const response = await fetch(url, {
method: 'GET',
cache: 'no-cache',
mode: 'cors',
headers: {
Authorization: 'Basic ' + btoa(':' + pat),
Accept: 'application/json',
}
})
return await response.json()
}
// get the connectionData from Azure DevOps
async function getConnectionData() {
return await ado('connectionData')
}
function topText(text) {
var p = document.createElement('p');
p.innerHTML = text
document.body.prepend(p)
return p
}
// show the connection Data at the top of the window
async function showConnectionData() {
try {
const result = await getConnectionData();
topText(`Azure DevOps access authenticated as: ${result.authenticatedUser.providerDisplayName}`)
} catch(err) {
const p = topText(`${err} - See console`)
p.style.color = "red";
p.style.fontWeight = "999"
}
}
async function tryFetch() {
try {
await showConnectionData()
} catch(err) {
console.log(err);
}
}
document.addEventListener("DOMContentLoaded", function(event) {
tryFetch()
});
})();
</script>
</body>
</html>