I'm trying to send a HTTP request from a Extension in which I need to change the User-Agent.
My code looks like this:
function getXMLHttpRequest(method, url, extraHeaders) {
var xhr = new XMLHttpRequest();
xhr.open(method, url, true)
for (var headerKey in extraHeaders) {
xhr.setRequestHeader(headerKey, extraHeaders[headerKey]);
}
return xhr;
}
//....
getXMLHttpRequest("POST", "....", { "User-Agent": "Blahblahblah" })
Then, I get an error "Refused to set unsafe header: UserAgent"
I need to change that because my Backend needs to have an special User-Agent, is it possible to do that from an extension?
I tried webRequest API, to change the header before sending the request, but it says it does not work with XMLHttpRequest made from extensions in order to prevent locking.
You can easily change the User-Agent header with the webRequest API.
For sample code, see Associate a custom user agent to a specific Google Chrome page/tab.
Take the code from that answer, and change "main_frame", "sub_frame" to "xmlhttprequest" to modify network requests initiated via XMLHttpRequest.
Obviously, to prevent deadlocks, this method does not work with synchronous requests ( i.e. when the third parameter of xhr.open is set to false).
Related
Suppose I enter a (public) website that makes 3 XHR/fetch calls on 3 different endpoints:
https://api.example.com/path1
https://api.example.com/path2
https://api.example.com/path3
What I want to achieve is intercept the call to https://api.example.com/path2 only, redirect it to a local service (localhost:8000) and let path1 and path3 through to the original domain.
What kind of options do I have here? I have studied a lot of approaches to this issue:
DNS rewriting - this solution is not suitable as I still have to intercept path1 and path3, only redirect them to the original IPs and try to mimic the headers as much as possible - which means I would have to do a specific proxy configuration for each intercepted domain - this is unfeasible
Chrome extensions - found none to deal specifically with single endpoint intercepting
Overwriting both fetch and XmlHttpRequest after page load - still doesn't cover all scenarios, maybe some websites cache the values of fetch and XmlHttpRequest before page load (?)
Combining the chrome extension and fetch overwrite will work.
download an webextension that let you load javascript code before a given page loads, e.g. User JavaScript and CSS
Add the following script to run before your page loads, base on: Intercepting JavaScript Fetch API requests and responses
const { fetch: originalFetch } = window;
window.fetch = async (...args) => {
let [resource, config ] = args;
// request interceptor starts
resource = resource === "https://api.example.com/path2" ? "http://localhost:8000/path2" : resource
// request interceptor ends
const response = await originalFetch(resource, config);
// response interceptor here
return response;
};
I want an existing application (which I do not control) to send information to an Azure function.
The application first sends a HTTP OPTIONS request, and will then regularly send HTTP POST messages.
The problem I have is that the application expects a header "Allow : POST,OPTIONS" in the response from the Azure function on the OPTIONS request. If the header is not present, it will not continue (instead, it throws an error : 'POST is not allowed')
When trying to set the header in Azure functions, I get the following error message
System.Net.Http: Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects.
I did enable CORS for all locations, and allowed all methods in the configuration.
module.exports = function (context, req)
{
//context.log('JavaScript HTTP trigger function processed a request.');
if (req.method == "OPTIONS")
{
context.res =
{
body: "",
headers:
{
//"Access-Control-Allow-Methods" : "POST,OPTIONS",
"allow" : "POST,OPTIONS"
},
status: 200,
};
}
context.done();
}
The specification say that the Allow header should be set for a 405 response. If the header is empty, nothing is allowed. However, there is no logic defined for when the header is not present at all.
Is there a method through which I can send this header in response to the HTTP OPTIONS ?
The error is expected. Function runtime is based on C#, when the response tries to add the Allow header, underlying C# code checks its name. It's by design that Allow is a read-only header in HttpContentHeaders hence we can't add it in HttpResponseHeaders.
Here are two workarounds for you to refer.
Use a custom header name like Allow-Method.
Create a new Function app, it uses Function runtime 2.0 by default, where we can set Allow header.
If you are editing this through the portal, navigate to the integrate section of the function and select POST and OPTIONS methods.
Have you tried adding the allowed methods to the function.json files as noted in the documentation?
Example below:
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"post",
"options"
]
Solved it through putting an APIM in front of teh logic app. This APIM just returns a 200 in case of the OPTIONS request, and calls the logic app for the subsequent HTTP post requests
I add a listener to modify HTTP Headers like below in my chrome extension:
chrome.webRequest.onBeforeSendHeaders.addListener(my_listener, {urls: ["<all_urls>"]}, ["blocking", "requestHeaders"]);
Normally, it will capture every HTTP request sent by the web pages, but it doesn't work when another chrome extension send a request with XMLHTTPRequest.
What the other extension does:
var xhr = new XMLHttpRequest;
xhr.open('GET', 'http://example.com/');
xhr.send()
I have a node.js server running express. I'm trying to write several tests for it in order to confirm standard behavior in the future when someone else may work on it. The server processes the request's header, the referrer and origin fields specifically. Using Jquery's ajax method, I was able to send ajax requests to the server. I found that I was able to set the referrer field. However, I can't seem to set the origin. Is there any way to spoof the origin in node.js?
Edit:
For clarification, I'm not running this code through a browser, but from the command line. Normally the ajax call would be run from a webpage, but as I'm writing tests to be run from Mocha, the origin isn't set.
Due to security reasons, the browser will not allow you to manually set your request origins. To spoof your request origin, you will have to make the request server-side:
var http = require('http');
var opt = {
host: 'yoursite.com',
path: '/test',
headers: { origin: 'http://spoofedorigin.com'}
};
http.get( opt );
Seems like I have a cross domain access problem.
I've seen some solutions that are indicating to add "Access-Control-Allow-Origin: *", but I don't know where I can do this.
Do I need to create some handler?
I'm using WCF Web API.
Error: XMLHttpRequest cannot load http://localhost:8081/Song/0. Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
EDIT
I've noticed that this is only happens when HTTP method is PUT or DELETE.
I can successfully make requests with GET or POST.
I'm making the request using jquery.
$.ajax({
url: Settings.RESTfulEndPointFor('Song/' + songID),
type: 'DELETE',
success: function (response) {
callback(response);
}
});
I don't know why, but it seems like this is resulting in method OPTIONS with Access-Control-Request-Method: DELETE.
Does any one know what causing this?
Any help is appreciated.
I had this problem when connecting to a WCF RESTful service via AJAX calls
My javascript was this:
var GetData= function(){
var data;
$.ajax({
url: this.server + "/data",
async: false,
type: "GET",
success: function (success) {
data = success;
}
});
return data;
};
My service endpoint was opened with this code
ServiceHost host = new ServiceHost(new MyService());
host.Open();
All the important data is stored in the App.config file, I did not have to change that file for this fix.
I knew I had to add the headers somewhere before the response message was sent.
After some searching and hacking I found the Authorization property of a ServiceHost object. The Authorization property is an instance of the ServiceAuthorizationBehavior class whose objects have a property called ServiceAuthorizationManager which is an instance of the ServiceAuthorizationManager class.
By creating a new class that inherits from the ServiceAuthorizationManager and setting it to the ServiceAuthorizationManager property of the Authorization behavior of your ServiceHost instance, you can intercept all calls to your service.
This is how I have implemented my class
public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
HttpResponseMessageProperty prop = new HttpResponseMessageProperty();
prop.Headers.Add("Access-Control-Allow-Origin", "*");
operationContext.OutgoingMessageProperties.Add(HttpResponseMessageProperty.Name, prop);
return true;
}
}
then right after I declare my ServiceHost object (before the host is opened) I add this line
host.Authorization.ServiceAuthorizationManager = new MyServiceAuthorizationManager();
After doing this, rebuilding, and running my service the error message stopped showing up. Hooray!
Lastly, I read an article that described the ServiceHost class was designed for SOAP/WSDL services not RESTful services. For RESTful services the WebServiceHost object should be used.
So
ServiceHost host = new ServiceHost(new MyService());
host.Open();
becomes
WebServiceHost host = new WebServiceHost(new MyService());
host.Open();
You must add references to the following assemblies:
System.ServiceModel.Web
Hope this helps.
Sources:
http://social.msdn.microsoft.com/Forums/en/wcf/thread/97ddb118-fdfd-4651-9e61-4d822861325f
http://www.c-sharpcorner.com/uploadfile/dhananjaycoder/webservicehost-hosting-a-wcf-rest-service/
http://social.msdn.microsoft.com/forums/en-us/wcf/thread/551409FD-DD77-40EF-8B78-DC8B3D7EA0BA
Normally you put this in header of response. So put it in header where you modify/insert other header values like this
header('Access-Control-Allow-Origin: *) //change it according to however header is set in wcf , since this is php syntax
Point is your response should have this header.
The request you are seeing with the OPTIONS method and an Access-Control-Request-Method: DELETE header is called a "preflight request". The CORS specification requires this for requests with methods that have side effects (like DELETE) to ensure the resource is ok with the request.
Check out this section of the spec >>
http://www.w3.org/TR/cors/#cross-origin-request-with-preflight0
Unfortunately I don't know how to make this type of request work with wcf web api.
I have created
AllowCrossDomainRequestHandler : DelegatingChannel
and for each response I'm registering this header:
response.Headers.Add("Access-Control-Allow-Origin", "*");
I got this to work using the following response headers:
res.writeHead(200, {
'Content-Type': 'text/plain',
'Access-Control-Allow-Methods': 'DELETE, POST, GET, OPTIONS',
'Access-Control-Allow-Origin': '*'
});
First, with most web browsers there is no way to actually get around the cross-domain restriction. Most won't even let you change the "accept" header. So you have to use JSONP. JSONP is a way of getting JSON data from a cross-domain service, but it is returned in the form of a javascript snippet - which is allowed. The way it works is that you provide the callback function name to the service, then the cross-domain service returns a simple javascript with the actual JSON values embedded as the parameters to your callback function. This is really easy to do now with WCF WebApi (preview 6). Install it in VS 2010 with NuGet. Once you have it installed, look here for more information.