如何通过JavaScript访问页面的HTTP响应头?
与此问题相关,该问题已被修改为询问访问两个特定的HTTP报头。
相关: 如何通过JavaScript访问HTTP请求报头字段?
如何通过JavaScript访问页面的HTTP响应头?
与此问题相关,该问题已被修改为询问访问两个特定的HTTP报头。
相关: 如何通过JavaScript访问HTTP请求报头字段?
当前回答
和许多人一样,我一直在网上搜索,没有真正的答案:(
I've nevertheless find out a bypass that could help others. In my case I fully control my web server. In fact it is part of my application (see end reference). It is easy for me to add a script to my http response. I modified my httpd server to inject a small script within every html pages. I only push a extra 'js script' line right after my header construction, that set an existing variable from my document within my browser [I choose location], but any other option is possible. While my server is written in nodejs, I've no doubt that the same technique can be use from PHP or others.
case ".html":
response.setHeader("Content-Type", "text/html");
response.write ("<script>location['GPSD_HTTP_AJAX']=true</script>")
// process the real contend of my page
现在每一个html页面加载从我的服务器,有这个脚本执行的浏览器在接收。然后,我可以很容易地从JavaScript检查变量是否存在。在我的用例中,我需要知道我是否应该使用JSON或JSON- p配置文件来避免CORS问题,但同样的技术可以用于其他目的[即:在开发/生产服务器之间选择,从服务器获取REST/API密钥等....]
在浏览器上,你只需要直接从JavaScript检查变量,在我的例子中,我用它来选择我的Json/JQuery配置文件
// Select direct Ajax/Json profile if using GpsdTracking/HttpAjax server otherwise use JsonP
var corsbypass = true;
if (location['GPSD_HTTP_AJAX']) corsbypass = false;
if (corsbypass) { // Json & html served from two different web servers
var gpsdApi = "http://localhost:4080/geojson.rest?jsoncallback=?";
} else { // Json & html served from same web server [no ?jsoncallback=]
var gpsdApi = "geojson.rest?";
}
var gpsdRqt =
{key :123456789 // user authentication key
,cmd :'list' // rest command
,group :'all' // group to retreive
,round : true // ask server to round numbers
};
$.getJSON(gpsdApi,gpsdRqt, DevListCB);
对于任何想要检查我代码的人: https://www.npmjs.org/package/gpsdtracking
其他回答
这是一个老问题。不确定何时支持变得更广泛,但getAllResponseHeaders()和getResponseHeader()现在似乎是相当标准的:http://www.w3schools.com/xml/dom_http.asp
使用XmlHttpRequest可以调出当前页面,然后检查响应的http报头。
最好的情况是只做一个HEAD请求,然后检查头。
要了解一些这样做的例子,请查看http://www.jibbering.com/2002/4/httprequest.html
这只是我的个人意见。
对于那些寻找一种方法来解析所有HTTP头到一个对象,可以访问作为字典头["content-type"],我已经创建了一个函数parseHttpHeaders:
function parseHttpHeaders(httpHeaders) {
return httpHeaders.split("\n")
.map(x=>x.split(/: */,2))
.filter(x=>x[0])
.reduce((ac, x)=>{ac[x[0]] = x[1];return ac;}, {});
}
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = parseHttpHeaders(req.getAllResponseHeaders());
// Now we can do: headers["content-type"]
(2021)一个没有额外HTTP调用的应答
一般来说,读取顶级HTML导航的任意HTTP响应头是不可能的,如果你控制了服务器(或中间箱),想要向JavaScript公开一些信息,而这些信息只能通过头来公开:
可以使用Server-Timing报头公开任意键值数据,JavaScript可以读取这些数据。
(*支持的浏览器:Firefox 61, Chrome 65, Edge 79;目前还没有Safari浏览器,也没有在2021年9月发布的计划;没有IE)
例子:
server-timing: key;desc="value"
你可以对多个数据块多次使用这个头文件:
server-timing: key1;desc="value1"
server-timing: key2;desc="value2"
或者使用它的精简版本,在一个标题中公开多个数据,以逗号分隔。
server-timing: key1;desc="value1", key2;desc="value2"
Wikipedia如何使用这个报头来暴露缓存命中/错过的信息:
代码示例(需要考虑在Safari和IE中缺乏浏览器支持):
if (window.performance && performance.getEntriesByType) { // avoid error in Safari 10, IE9- and other old browsers
let navTiming = performance.getEntriesByType('navigation')
if (navTiming.length > 0) { // still not supported as of Safari 14...
let serverTiming = navTiming[0].serverTiming
if (serverTiming && serverTiming.length > 0) {
for (let i=0; i<serverTiming.length; i++) {
console.log(`${serverTiming[i].name} = ${serverTiming[i].description}`)
}
}
}
}
在受支持的浏览器中记录cache = hit-front。
注:
as mentioned on MDN, the API is only supported over HTTPS if your JS is served from another domain, you have to add Timing-Allow-Origin response header to make the data readable to JS (Timing-Allow-Origin: * or Timing-Allow-Origin: https://www.example.com) Server-Timing headers support also dur(header) field, readable as duration on JS side, but it's optional and defaults to 0 in JS if not passed regarding Safari support: see bug 1 and bug 2 and bug 3 You can read more on server-timing in this blog post Note that performance entries buffers might get cleaned by JS on the page (via an API call), or by the browser, if the page issues too many calls for subresources. For that reason, you should capture the data as soon as possible, and/or use PerformanceObserver API instead. See the blog post for details.
和许多人一样,我一直在网上搜索,没有真正的答案:(
I've nevertheless find out a bypass that could help others. In my case I fully control my web server. In fact it is part of my application (see end reference). It is easy for me to add a script to my http response. I modified my httpd server to inject a small script within every html pages. I only push a extra 'js script' line right after my header construction, that set an existing variable from my document within my browser [I choose location], but any other option is possible. While my server is written in nodejs, I've no doubt that the same technique can be use from PHP or others.
case ".html":
response.setHeader("Content-Type", "text/html");
response.write ("<script>location['GPSD_HTTP_AJAX']=true</script>")
// process the real contend of my page
现在每一个html页面加载从我的服务器,有这个脚本执行的浏览器在接收。然后,我可以很容易地从JavaScript检查变量是否存在。在我的用例中,我需要知道我是否应该使用JSON或JSON- p配置文件来避免CORS问题,但同样的技术可以用于其他目的[即:在开发/生产服务器之间选择,从服务器获取REST/API密钥等....]
在浏览器上,你只需要直接从JavaScript检查变量,在我的例子中,我用它来选择我的Json/JQuery配置文件
// Select direct Ajax/Json profile if using GpsdTracking/HttpAjax server otherwise use JsonP
var corsbypass = true;
if (location['GPSD_HTTP_AJAX']) corsbypass = false;
if (corsbypass) { // Json & html served from two different web servers
var gpsdApi = "http://localhost:4080/geojson.rest?jsoncallback=?";
} else { // Json & html served from same web server [no ?jsoncallback=]
var gpsdApi = "geojson.rest?";
}
var gpsdRqt =
{key :123456789 // user authentication key
,cmd :'list' // rest command
,group :'all' // group to retreive
,round : true // ask server to round numbers
};
$.getJSON(gpsdApi,gpsdRqt, DevListCB);
对于任何想要检查我代码的人: https://www.npmjs.org/package/gpsdtracking