I use google app script (where we usually use almost raw js, without libs and etc).
So I need to use proxy server (need dynamic-changing ip address).
But when i make request, proxy server calls back
This is a proxy server. Does not respond to non-proxy requests.
In common way, making http request in google app scrip seems like this:
function make_some_request() {
const url = 'https://www.google.com/';
var headers = {
"Content-Type" : "application/json; charset=utf-8",
}
var payload = []; // some data if we need post request
var options = {
"method" : "POST",
'headers' : headers,
'payload' : JSON.stringify(payload)
};
try {
var response = UrlFetchApp.fetch(url, options);
return JSON.parse(response);
} catch (error) {
log("make_some_request", "ERROR: " + error);
}
}
So, i can't understand what should i make with my request to use proxy server. How we make call through proxy server in common way (in raw HTTP). What headers or payload should i send to make this request a proxy-request?
P.S. as i know, google app script doesn't support another classes to make https requests. So all i have is almost raw HTTP.
Related
What is the reason the server is returning object as 'undefined' and 'XMLHttpRequest cannot load the "URL" Response for preflight is invalid (redirect).
Flow of app - its just a normal post service sending document details to the server in return should return an object holding various parameters, but its returning 'undefined'
The service for posting the document
fileUpload: {
method: 'POST',
url: config.apiPath + 'employee/service/pushRecords', //this is the URL that should return an object with different set of parameters (currently its returning Error error [undefined])
isArray: false,
params: {},
headers: {
'content-type': undefined
}
},
above service i have used after creating formdata w.r.t document
function registerFormdata(files, fieldName) {
files = files || [];
fieldName = fieldName || 'FileSent';
var returnData = new FormData();
_.each(files, function (file, ind) {
returnData.append(fieldName,file);
});
return returnData;
}
now this is the controller where these services are used
function sendFilesToServer() {
var formData = employeePushService.registerFormdata(directive.dropZoneFile.fileToUpload);
return docUploadService.fileUpload(formData)
.then(function(document) {
// Extra actions but here the server should be returning an object with set of parameters but in browser console its Error [undefined]
}).catch(logger.error);
}
Assuming that the URL target in yout post is correct, it seems that you have a CORS problem, let me explain some things.
I don't know if the server side API it's developed by yourself, if it is, you need to add the CORS access, your server must return this header:
Access-Control-Allow-Origin: http://foo.example
You can replace http://foo.example by *, it means that all request origin will have access.
First, you need to know that when in the client you make an AJAX CORS request, your browser first do a request to the server to check if the server allow the request, this request is a OPTION method, you can see this if, for example in chrome, you enable the dev tools, there, in the network tab you can see that request.
So, in that OPTIONS request, the server must set in the response headers, the Access-Control-Allow-Origin header.
So, you must check this steps, your problem is that the server side is not allowing your request.
By the way, not all the content-type are supported in CORS request, here you have more information that sure will be helpfull.
Another link to be helpfull for the problem when a 302 happens due to a redirect. In that case, the POST response must also include the Access-Control-Allow-Origin header.
I'm getting the following error using AJAX to call an API on UPS
XMLHttpRequest cannot load https://wwwcie.ups.com/rest/Ship. Response to
preflight request doesn't pass access control check: No 'Access-Control-Allow-
Origin' header is present on the requested resource. Origin
'http://localhost:63786' is therefore not allowed access.
AJAX Call:
$.ajax({
url: "https://wwwcie.ups.com/rest/Ship",
type: "POST",
dataType: 'json',
crossDomain: true,
contentType: 'application/json',
data: JSON.stringify(message),
success: function (result) {
//code to execute on success
}
error: function (result) {
//code to execute on error
}
})
I have no control over the API server so I cannot modify the headers being sent back. I've tried JSONP, changing the headers I send, and a number of other solutions to no avail. I've read that making a server-side proxy could be a possible fit but I'm not sure how I would go about this. Any advice/code samples on possible solutions would be greatly appreciated. Thanks in advance.
What is to stop a malicious website from sending requests to your bank's web app and transferring all of your money? To prevent these types of shenanigans, if you're using a web browser, the server must explicitly state which remote origins are allowed to access a certain resource, if any.
If you need a key to access it, then CORS probably isn't enabled. You can always double check by looking at the response headers. See this:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
So as others have already mentioned, you can get around this by making the request from your own server (where the headers don't identify it as a browser and subject to CORS limitations), and proxy it to your client side app.
Assuming you're using Node/Express, something like this should work:
const express = require('express');
const app = express();
const myHeaders = new Headers();
const myInit = { method: 'GET',
headers: myHeaders,
mode: 'cors',
cache: 'default' };
app.get('/ups/stuff/stuff', (req, res) => {
fetch('/ups/api/stuff', myInit)
.then(response => response.json())
.then(json => res.json(json);
});
app.listen(3000);
The native fetch API is neat because you can use it on both client and server, and it supports promises like jQuery.
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
Using angular v1.3.1 i got a singular the following problem trying to implement a facade for making http request to a REST + JSON interface in the backend of the web app.
I got something like this in the code:
findSomething(value: number): ng.IPromise<api.DrugIndication[]> {
const getParams = { 'param' : 'value' };
const config:ng.IRequestShortcutConfig = {
headers: {
"Content-Type" : "application/json"
},
data: getParams
}
return this.$http.get(url,config);
}
And when the times comes to invoke it, i got an 400 Bad Request (btw: Great name for a band!) because the backend (made with Play for Scala) rejects the request inmediately. So making an inspection in the request i see that no data is being send in the body of the request/message.
So how i can send some data in the body of and HTTP Get request using angular "$http.get"?
Additional info: This doesn't happen if i the make request using the curl command from an ubuntu shell. So probably is an problem between Chrome and angular.js
If you inspect the network tab in chrome development tools you will see that this is a pre-flight OPTIONS request (Cross-Origin Resource Sharing (CORS)).
You have two ways to solve this.
Client side (this requires that your server does not require the application/json value)
GET, POST, HEAD methods only
Only browser set headers plus these
Content-Type only with:
application/x-www-form-urlencoded
multipart/form-data
text/plain
Server side
Set something like this as a middleware on your server framework:
if r.Method == "OPTIONS" {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type,Authorization")
w.Header().Set("Access-Control-Max-Age", "86400") // firefox: max 24h, chrome 10min
return
}
For your specific framework this should work
Using config.data will send the data in the request body, use
config.params = getParams
This is from the documentation :
params – {Object.} – Map of strings or objects which will be serialized with the paramSerializer and appended as GET parameters
Is it possible to call a web service though a proxy server using angular $http?
My webservices is hosted in my server and we have a proxy server is it possible that i can redirect my request through that proxy not by changing device property but by through code?
$http({
method: $scope.method,
url: $scope.url,
params: { "member_id": "998014437" }
})
.then(function (response) {
$scope.status = response.status,
$scope.data = response.data;
}, function (response) {
$scope.data = response.data || "Request failed";
$scope.status = response.status;
}
);
As far as I know there aren't any build in webproxy settings for XMLHttpRequest, so there aren't for angular $http too. The common practice for using a proxy on this matter is that you build a server side proxy page on your domain. Something like:
"/proxy.php?url=http://crossdomain.com/somedata.json"
This page basically make the web requests on server side and return the exactly same response to client with headers and everything. And then you make all your requests via this proxy page. Since the proxy url part is at the beginning of your actual url, you can customize this with a variable like url: proxyPrefix + $scope.url . If proxy prefix variable is empty, then the request will be done over the actual server.
I noticed that my Angular is creating OPTIONS request also before each POST request.
I'm using custom API Service for HTTP request handling.
app.service('ApiService', function ($http) {
/**
* Process remote POST request to give URL with given params
* #param {String} url
* #param {String} POST params
* #return {JSON} response from server
*/
this.doHttpRequest = function (type, url, params) {
return $http({
method: type,
url: url,
data: params,
timeout: 5000,
headers: {
"Content-Type": "application/json",
}
});
}
});
Question is:
How can i disable it (which config values put where)?
Is OPTIONS good for something?
I think that is it something like "Handshake between 2 servers".
Angular version: 1.2.15
Thanks for any advice.
That isn't Angular. It is XMLHttpRequest.
Complex cross-origin HTTP requests require a pre-flight OPTIONS request so the browser can find out if the other server will grant permission for the Ajax request.
Short of making sure the Ajax request you are making is simple, there is no way to prevent the OPTIONS request.
A simple request:
Only uses GET, HEAD or POST. If POST is used to send data to the server, the Content-Type of the data sent to the server with the HTTP POST request is one of application/x-www-form-urlencoded, multipart/form-data, or text/plain.
Does not set custom headers with the HTTP Request (such as X-Modified, etc.)
Unless you wish to give up sending JSON, you can't use a simple request for this.
I run into a close situation, need to get JSON with Cross-site HTTP requests and fixed it by using jQuery request, instead of angularjs
$.getJSON('http://www.host.com/test.json', '', function (data) {
if (meta) {
console.log("jq success :" + JSON.stringify(data));
}
console.log("jq success, but empty JSON");
})
.done(function () {
console.log("jq second success");
})
.fail(function (data) {
console.log("jq fail " + JSON.stringify(data));
})
.always(function () {
console.log("jq complete");
});
I used Amazon S3 CDN, and OPTIONS requests didn't work well with it, so this saved me. The answer from S3 server was:
This distribution is not configured to allow the HTTP request method that was used for this request. The distribution supports only cachable requests.