Cross Origin Put Request Methods - ajax

What are some successful methods for performing Cross Origin Put requests? I successfully used a Proxy to make a GET request and put it into a Dropdown list as can be seen here >> Create Dropdown list from API Query >>but have not been able to use the same process in making a PUT Request?
Thoughts?

I was able to successfully get a PUT request to work just peachy through the use of the proxy in javascript.
$.ajaxPrefilter( function (options) {
if (options.crossDomain && jQuery.support.cors) {
var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');
options.url = http + '//cors-anywhere.herokuapp.com/' + options.url;
//options.url = "http://cors.corsproxy.io/url=" + options.url;
}
});
Once the Proxy was established, I used the chrome extension (now a desktop app) Postman to get the PUT HTML code. This was done by first getting the PUT request to work in Postman and then selecting the "code" link (below the "send" button) and selecting "JavaScript Jquery AJAX" from the drop-down. Here is an example of outputted code from Postman.
var settings = {
"async": true,
"crossDomain": true,
"url": "https://[apiurl].com",
"method": "PUT",
"headers": {
"content-type": "text/xml",
"cache-control": "no-cache",
"postman-token": "[token]"
},
"data": "<this_is_the_xml_data_youre_sending>"
}
$.ajax(settings).done(function (response) {
console.log(response);
});
Once the code is copied from Postman, put the proxy code and Postman javascript into an HTML page and watch the PUT request happen.

Related

AWS Lambda Set-Cookie header not setting in the browser

I'm trying to set a cookie in my aws lambda function response. I don't have any header mapping as I'm using lambda proxy integration with API Gateway. The response code looks like this in the lambda function:
exports.handler = async (event) => {
const response = {
statusCode: 200,
"multiValueHeaders": {
"Set-Cookie": ["gtgm=6c7729687d5ff1a05f1a5dfb15ce3b8fa3f2b590; path=/; expires=Fri, 13-Feb-2032 13:27:44 GMT; secure; HttpOnly; SameSite=None"]
},
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Credentials": true,
},
};
return response;
};
I use fiddler to check the response and I can see the "Set-Cookie..." in the response which leads me to believe that the code above is correct? The issue is that the browser just ignores it and doesn't set any cookies at all except for the AWS DNT cookie. I'm not sure what else to check or if I've missed anything in the cookie config.
This is what my request looks like:
<Button
onClick={() => {
fetch(
"https:mysupercoolapi.com/cookie-test/",
{
// credentials: "include",
headers: {
"Content-Type": "application/json",
// "Access-Control-Allow-Credentials": "true",
},
}
)
.then((response) => response.json())
.then((data) => {
console.log(data);
});
}}
>
Cookie Test
</Button>
Not sure what I'm missing or where I'm going wrong.
I magaed to figure this one out myself. The setup above was fine but the browser requires you to have the following set properly in order for it to actually set the cookie:
In the request: Set "credentials" as include. Depending on what library you're using (fetch would be credentials: "include"). You can see it is commented out in my original post above which is not correct.
In the Response header in the Lambda function you need to set you origin e.g., "Access-Control-Allow-Origin": "http://localhost:3002". After testing I switched it to my actual domain. If there's a way to keep this set to the actual domain but still have it work while testing on localhost please let me know.
In API Gateway you need to set the CORS values as in the screenshot below to ensure the preflight (OPTINOS) call is made correctly as well.
The key is to have both the request and response headers configured correctly. This is harder to do when using something like AWS but much easier with something like express.js where you can use the middleware.

asp.net core Ajax requests gives 400 bad request but POSTMAN works

I am facing trouble with ajax request in asp.net core blazor application. I have tried almost everything i can find on stackoverflow related to ajax post call results in 400 bad request
I have following controller
[Route("api/{controller}/{action}/{id?}")]
public class BoldReportsAPIController : ControllerBase, IReportController
{
// Report viewer requires a memory cache to store the information of consecutive client request and
// have the rendered report viewer information in server.
private IMemoryCache _cache;
// IHostingEnvironment used with sample to get the application data from wwwroot.
private IWebHostEnvironment _hostingEnvironment;
public BoldReportsAPIController(IMemoryCache memoryCache, IWebHostEnvironment hostingEnvironment)
{
_cache = memoryCache;
_hostingEnvironment = hostingEnvironment;
}
// Post action to process the report from server based json parameters and send the result back to the client.
[HttpPost]
public object PostReportAction([FromBody] Dictionary<string, object> jsonArray)
{
return ReportHelper.ProcessReport(jsonArray, this, this._cache);
}
}
When i make request with postman it works fine as shown below.
But when i make ajax call it gives 400 bad request error.
I have literally replaced original ajax call with the code generated from postman but that code doesn't work also.
var settings = {
"async": true,
"crossDomain": true,
"url": "https://localhost:44313/api/BoldReportsAPI/PostReportAction",
"method": "POST",
"headers": {
"content-type": "application/json",
"cache-control": "no-cache",
"postman-token": "fbed680d-0143-ab86-24e6-176c16d713bf"
},
"processData": false,
"data": "{\"reportAction\":\"ReportLoad\",\"isReloadReport\":false,\"controlId\":\"report-viewer\",\"reportPath\":\"sales-order-detail\",\"enableVirtualEvaluation\":false,\"reportServerUrl\":\"\",\"processingMode\":\"remote\",\"locale\":\"en-US\",\"accessInternalValue\":false,\"customBrandSettings\":{\"hideHelpLink\":false,\"customDomain\":\"https://help.boldreports.com\",\"customBrandName\":\"Bold Reports\",\"customLinks\":[{\"name\":\"ESLicenseMessage\",\"url\":\"/licensing/license-token/\"}]}}\r\n"
}
$.ajax(settings).done(function (response) {
console.log(response);
});
It was due to ant forgery token. Apparently, ABP automatically adds antiforgery token so after adding
[IgnoreAntiforgeryToken(Order = 2000)]
to my action method, issue was resolved.
But it feels like I am breaking security.
While using ValidateAntiForgeryToken, you have to add the headers for the Report Viewer API interaction. You can refer to the below article to add the headers for your Report Viewer interaction. These need to be added with the ReportViewer introp.
https://help.boldreports.com/embedded-reporting/javascript-reporting/report-viewer/handle-post-actions/#add-custom-header-in-ajax-request

POST call to Add place to Google Maps fails on preflight

I'm trying to add custom places to Google Maps, and for that I try to send a POST request using this code:
httpPostAsync('https://maps.googleapis.com/maps/api/place/add/json?key=<MY_KEY>',
{
location: {
"lat": 32.12345,
"lng": 32.12345
},
"accuracy": 50,
"name": "Test123"
},
function(response) {
console.log(response);
});
function httpPostAsync(theUrl, params, callback)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
callback(xmlHttp.responseText);
}
xmlHttp.open("POST", theUrl, true); // true for asynchronous
//Send the proper header information along with the request
xmlHttp.setRequestHeader("Content-type", "application/json");
xmlHttp.setRequestHeader("Host", "maps.googleapis.com");
xmlHttp.send(JSON.stringify(params));
}
I run it from my site, lets say the address is https://www.example.com/maps.html.
I have an API key that has key restrictions from www.example.com/*.
Whenever I run this code, I receive this error:
XMLHttpRequest cannot load https://maps.googleapis.com/maps/api/place/add/json?key=<MY_KEY>. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://www.example.com' is therefore not allowed access. The response had HTTP status code 400.
Any ideas what may be the problem?

Access denied in IE 10 and 11 when ajax target is localhost

I'm trying to do a ajax call between a server (http) that is on internet. And target that to my own localhost. FF/Chrome/ ETC... works. It's ONLY an IE issue. IM USING IE 11 AND 10.
The request is don't even done. The "denied access" is thrown instantly.
This is the code. Just for you to see.
Is not the classical HTTP/HTTPS error in IE8 AND IE9. This is something else, but the documentation is not helpful.
$jq.ajax({
contentType: 'application/json',
url: url,
dataType: 'json',
crossDomain: true,
beforeSend: function (xhr) {
xhr.withCredentials = true;
xhr.setRequestHeader("Authorization", "Basic " + $jq.base64.encode(username and password));
},
success: function (data, status, headers) {},
error: function (xhr, status, error) {}
The status is 0 in xhr object and error is "Denied access"
Internet Explorer raises this error as part of its security zones feature. Using default security settings, an "Access is Denied" error is raised when attempting to access a resource in the "Local intranet" zone from an origin in the "Internet" zone.
If you were writing your Ajax code manually, Internet Explorer would raise an error when you try to open the resource. For example:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost/', true); // This line will trigger an error
xhr.send();
You can work around this error by adding the origin site to the "Trusted sites" security zone. You can test this by adding "http://client.cors-api.appspot.com" to your "Trusted sites" zone and using this test page at test-cors.org with your localhost site as the Remote URL.
In addition to the trusted site requirement I found that the problem was not fixed until I used the same protocol for the request as my origin, e.g. my test site was hosted on a https but failed with any destination using http (without the s).
This only applies to IE, Chrome just politely logs a warning in the debug console and doesn't fail.
If you are attempting to make cross-origin ajax requests in IE9, you'll need to use XDomainRequest instead of XMLHttpRequest. There is a jQuery plug-in that wraps XDR. You should be aware that there are some notable limitations of XDR.
Another option would be to use a library like this: https://github.com/jpillora/xdomain.
jQuery implements ajax calls using the XMLHttpRequest object which is not supported in IE9. You have to force it to use XDomainRequest instead.
I get around this problem using this jQuery plugin:
https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest
Note:
Do not use "http://www.domain.xxx" or "http://localhost/" or "IP" for URL in Ajax.
Only use path(directory) and page name without address.
false state:
var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'http://www.example.com/dir/getSecurityCode.php', true);
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);
true state:
var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'dir/getSecurityCode.php', true); // <<--- note
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);
function createAjax()
{
var ajaxHttp = null;
try
{
if(typeof ActiveXObject == 'function')
ajaxHttp = new ActiveXObject("Microsoft.XMLHTTP");
else
if(window.XMLHttpRequest)
ajaxHttp = new XMLHttpRequest();
}
catch(e)
{
alert(e.message);
return null;
}
//-------------
return ajaxHttp;
};

Crossdomain post with easyXDM

I'm trying to get a crossdomain post to work. I know I can easily use jsonp for GET, but I'm stuck as to how I can implement POST requests.
I've looked up easyXDM, but as I understand it the server also needs some kind of easyXDM implementation, in the form of a "cors" file or something.
Is that true? So if the server does not support it, there's no way to do a crossdomain post (without setting up a proxy, that is)
I've tried it myself with only local files:
<script type="text/javascript">
var xhr = new easyXDM.Rpc(/** The channel configuration*/{
remote: "name.html"
}, {
remote: {
request: {} // request is exposed by /cors/
}
});
</script>
And then do a request like this:
xhr.request({
url: "http://other.domain.be",
method: "POST",
data: {NEWS: "true", IMMO: "true" }
}, function(response) {
alert(response.status);
alert(response.data);
});
But that does nothing.
Yes, easyXDM.Rpc need to be initialized using the server cors url.
xhr = new easyXDM.Rpc({remote: "http://url/cors"}, {remote:{request:{}}});
If you don't want to use easyXDM, you can easily set up the server to accept all requests by adding : (doesn't supported by IE<8)
Header set Access-Control-Allow-Origin *
Header add Access-Control-Allow-Headers X-Requested-With
Header add Access-Control-Allow-Headers X-Request

Resources