A silent voice begins to softly speak.
const nasId = await fetch("http://connect.rom.miui.com/generate_204", {
redirect: "manual",
headers: { "Connection": "close" },
}).then(
(response) => {
console.log(`${response.status} ${response.url}`); // debug
return response.status === 204
? null
: new URL(response.url).searchParams.get("nasId");
}
);import TcpSocket from "react-native-tcp-socket";
function getNasId(): Promise<string | null> {
return new Promise((resolve, reject) => {
const socket = TcpSocket.createConnection(
{ host: "connect.rom.miui.com", port: 80 },
() => {
socket.write(
"GET /generate_204 HTTP/1.0\r\nHost: connect.rom.miui.com\r\nConnection: close\r\n\r\n",
);
},
);
let data = "";
socket.on("data", (chunk) => {
data += chunk.toString();
});
socket.on("close", () => {
const location = data.match(/Location:\s*(.*)/i);
if (!location) {
resolve(null);
return;
}
try {
const url = new URL(location[1].trim());
resolve(
url.searchParams.get("nasId") ??
url.pathname.split("/").pop() ??
null,
);
} catch {
resolve(null);
}
});
socket.on("error", (error) => {
socket.destroy();
reject(error);
});
});
}
In RN development, I need to request http://connect.rom.miui.com/generate_204 to detect network connectivity. This /generate_204 API returns a 204 No Content response when the network is available, but when the gateway requires authentication, it hijacks the HTTP request and redirects to the login page.
But when I use fetch to implement this logic, I found that even when a redirect occurs, fetch still returns a status code of 200. The partial code used is as follows:
The running result is shown below:
From the figure, we can see that when the network is available, response.status is 204, and when hijacked by the gateway it is 200, while response.url is always http://connect.rom.miui.com/generate_204
However, packet capture shows that the request was indeed correctly redirected:
So the problem is most likely with RN's fetch.
By checking the RN official documentation, I found that RN's fetch does not support redirect: manual, as shown below:
To intercept redirects in RN, the only option is to use react-native-tcp-socket to manually construct an HTTP request, and then directly parse the Location header to resolve the redirect URL. The code is as follows: