Javascript 如何拦截包括表单提交在内的所有http请求
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43813770/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to intercept all http requests including form submits
提问by lenniekid
I would like to intercept all http requests going out from my web page and add a parameter to the request body. My page includes forms - I also want to capture form submits. I have tried using Jquery ajaxSend and Javascript's setRequestHeader but both did not work for me. How do I achieve this?
我想拦截从我的网页发出的所有 http 请求,并向请求正文添加一个参数。我的页面包含表单 - 我还想捕获表单提交。我曾尝试使用 Jquery ajaxSend 和 Javascript 的 setRequestHeader,但两者都不适合我。我如何实现这一目标?
Thanks
谢谢
回答by sideshowbarker
https://developer.mozilla.org/en/docs/Web/API/Service_Worker_API
https://developer.mozilla.org/en/docs/Web/API/Service_Worker_API
Service workers essentially act as proxy servers that sit between web applications, and the browser and network (when available).
It takes the form of a JavaScript file that can control the web page/site it is associated with, intercepting and modifying navigation and resource requests
Service Worker 本质上充当位于 Web 应用程序、浏览器和网络(如果可用)之间的代理服务器。
它采用 JavaScript 文件的形式,可以控制与其关联的网页/站点,拦截和修改导航和资源请求
You register a service worker in your application code from a file named, e.g., sw.jsby doing this:
你在你的应用程序代码中从一个名为的文件中注册一个服务工作者,例如,sw.js通过这样做:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('sw.js').then(function(registration) {
console.log('Service worker registered with scope: ', registration.scope);
}, function(err) {
console.log('ServiceWorker registration failed: ', err);
});
});
}
And in the sw.jsfile (the actual service-worker code): To intercept requests, you attach a fetchevent listener to the service worker that calls the respondWith()method and does something with the .requestmember from the event object:
在sw.js文件中(实际的 service-worker 代码):要拦截请求,您将fetch事件侦听器附加到调用该respondWith()方法的 service worker,并对.request来自事件对象的成员执行某些操作:
self.addEventListener('fetch', function(event) {
event.respondWith(
// intercept requests by handling event.request here
);
});
A simple service worker that just passes through requests unchanged looks like this:
一个简单的 service worker 只是不变地传递请求,如下所示:
self.addEventListener('fetch', function(event) {
event.respondWith(
fetch(event.request)
);
});
To add a param to the request body, I think you need to serialize the request, modify that serialized request, then deserialize it to recreate a new request, then call fetch(…)with that new request.
要将参数添加到请求正文,我认为您需要序列化请求,修改该序列化请求,然后反序列化以重新创建新请求,然后fetch(…)使用该新请求进行调用。
So I think a service worker that does all that would look like this (untested):
所以我认为一个服务工作者会像这样(未经测试):
self.addEventListener('fetch', function(event) {
event.respondWith(
fetchWithParamAddedToRequestBody(event.request)
);
});
function fetchWithParamAddedToRequestBody(request) {
serialize(request).then(function(serialized) {
// modify serialized.body here to add your request parameter
deserialize(serialized).then(function(request) {
return fetch(request);
});
}
function serialize(request) {
var headers = {};
for (var entry of request.headers.entries()) {
headers[entry[0]] = entry[1];
}
var serialized = {
url: request.url,
headers: headers,
method: request.method,
mode: request.mode,
credentials: request.credentials,
cache: request.cache,
redirect: request.redirect,
referrer: request.referrer
};
if (request.method !== 'GET' && request.method !== 'HEAD') {
return request.clone().text().then(function(body) {
serialized.body = body;
return Promise.resolve(serialized);
});
}
return Promise.resolve(serialized);
}
function deserialize(data) {
return Promise.resolve(new Request(data.url, data));
}
Note:https://serviceworke.rs/request-deferrer_service-worker_doc.html, a page from the Service Worker Cookbook, is where I lifted that serialize(…)code/approach from—by way of the answer at How to alter the headers of a Request?—and it's worth taking a look at, because the code there has detailed annotations explaining what it's all doing
注意:https : //serviceworke.rs/request-deferrer_service-worker_doc.html是Service Worker Cookbook 中的一个页面,是我serialize(…)从中提取该代码/方法的地方 - 通过如何更改请求的标头的答案? ——值得一看,因为那里的代码有详细的注释,解释了它在做什么
回答by abdelhadi
try this code :
试试这个代码:
(function(send) {
XMLHttpRequest.prototype.send = function(data) {
var _valuToAdd = $("input[name='valuToAdd']").val();
this.setRequestHeader('valueName', _valuToAdd);
send.call(this, data);
};
})(XMLHttpRequest.prototype.send);

