Hello so i'm trying to call my backend and getting some strange issue with calling post method.
Remote Address:192.168.58.183:80
Request URL:http://192.168.58.183/ESService/ESService.svc/CreateNewAccount
Request Method:OPTIONS
Status Code:405 Method Not Allowed
Request Headersview source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,pl;q=0.6
Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:192.168.58.183
Origin:http://localhost:8100
Referer:http://localhost:8100/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) > AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93
Safari/537.36
Response Headersview source
Access-Control-Allow-Headers:Content-Type, Accept
Access-Control-Allow-Methods:POST,GET,OPTIONS
Access-Control-Allow-Origin:*
Access-Control-Max-Age:1728000
Allow:POST
Content-Length:1565
Content-Type:text/html; charset=UTF-8
Date:Mon, 02 Feb 2015 09:11:17 GMT
Server:Microsoft-IIS/7.5
X-Powered-By:ASP.NET
And my code looks like here i think this call is okay can someone review it?
$scope.RegisterUser = function(){
var us = {
UserName:$scope.userName,
Password:$scope.password,
UserRoleID:null,
Company:$scope.company,
Terms:$scope.terms,
ID:null,
BuyerID:app.buyerId
};
$http({method:'POST', url:app.wcf + '/CreateNewAccount', data:{us:us}})
.then(
function(resp){
app.Logger(resp.data);
},
function(err){
app.Logger(err);
})};
So maybe i'm doing something wrong or i need to pass optional config to http?
Normally, browsers will not allow your site's JavaScript to read the data from a cross-origin request. This is because your site might be instructing the browser to get information from the user's online banking, company intranet, or some other private site. This is called The Same Origin Policy.
A standard called CORS allows a site to give permission to another site to read data from it.
Since POST requests can have side effects, an additional layer of security is added. Before the browser will make the POST request, it will make a pre-flight OPTIONS request to ask for permission to make the POST request.
Your server is not configured to handle that OPTIONS request (and probably isn't configured to return the CORS headers for the POST request either).
You need to set up CORS support if you want to allow your JavaScript to make requests to it from a different origin.
This is a pre flight request and is used to enable CORS there is no need to be concerned this is normal.
Related
I am trying to understand how the whole CORS policy works. To explain my confusion, let me give you an example:
$.get("https://www.google.com", function(response) { alert(response) });
The above request will return with the following error:
XMLHttpRequest cannot load https://www.google.com/. Redirect from 'https://www.google.com/' to 'https://www.google.ca/?gfe_rd=cr&ei=TlqUWeGEH5HRXqW6utgI' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://fiddle.jshell.net' is therefore not allowed access.
Now in order for that to work, google would have to white-list https://fiddle.jshell.net.
Now, if I were to try the same thing on a restful API page, that will work. My question is really simple, Why?
Trying to analyze this, I tried hitting an API and analyzing its response:
https://apigee.com/console/bing?req=%7B%22resource%22%3A%22web_search%22%2C%22params%22%3A%7B%22query%22%3A%7B%22query%22%3A%22sushi%22%2C%22sources%22%3A%22web%22%7D%2C%22template%22%3A%7B%22format%22%3A%22json%22%7D%2C%22headers%22%3A%7B%7D%2C%22body%22%3A%7B%22attachmentFormat%22%3A%22mime%22%2C%22attachmentContentDisposition%22%3A%22form-data%22%7D%7D%2C%22verb%22%3A%22get%22%7D
Response:
HTTP/1.1 200
Date:
Wed, 16 Aug 2017 14:31:32 GMT
Content-Length: 266
Connection: keep-alive
Content-Type: application/json; charset=utf-8
Server: Apigee Router
X-Content-Type-Options: nosniff
I came to conclusion that it must be the headers. Specifically I belive that it is this header: Content-Type: application/json; But I don't know for sure, I am trying to understand this and hoping somebody here can explain to me.
So I did 2 tests: running your code $.get("https://www.google.com", function(response) { alert(response) }); snippet from the console and requesting https://www.google.com from https://apigee.com/console/others
I think what happens in the 1st case is the fact that the request is done from the client, next request headers are sent:
:authority:www.google.com
:method:GET
:path:/?_=1502896196820
:scheme:https
accept:*/*
accept-encoding:gzip, deflate, br
accept-language:en-US,en;q=0.8
origin:https://stackoverflow.com
referer:https://stackoverflow.com/questions/45717044/understanding-page-response
user-agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3187.0 Safari/537.36
x-chrome-uma-enabled:1
x-client-data:CJG2yQEIo7bJAQiMmMoBCKudygEIs53KAQjRncoBCKiiygE=
Since Google does not reply with 'Access-Control-Allow-Origin: *' - client, and in the request I have origin:https://stackoverflow.com, Chrome in my case throws CORS error.
In the 2nd test, using https://apigee.com/console/others and requesting https://www.google.com , apigee.com seems to overwrite headers and sends:
GET / HTTP/1.1
Host:
www.google.com
X-Target-URI:
https://www.google.com
Connection:
Keep-Alive
Also, from DEV console, I can see it does server to server call so no client involved in throwing CORS, thus I am getting the responses with Google page.
UPDATE:
Regarding JSON API requests, here is some interesting info from Google CloudPlatform about CORS
Note: CORS configuration applies only to XML API requests. For JSON
API requests, Cloud Storage returns the Access-Control-Allow-Origin
header with the origin of the request.
Thus, if the request is performed from the client, a client should not throw CORS errors since it gets Access-Control-Allow-Origin with the same origin it sent.
However, different APIs and clients might process requests differently. Thus, sometimes Firefox throws CORS while Chrome does not.
I got this code:
var req = new HttpRequest();
req.open("POST", "http://localhost:8031/rest/user/insert");
req.setRequestHeader("Content-type", "application/json");
req.send(json.stringify(user_map));
But, instead of sending the POST verb, when I see it in fiddler I see this:
OPTIONS http://localhost:8031/rest/user/insert HTTP/1.1
Host: localhost:8031
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://127.0.0.1:3030
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.33 (KHTML, like Gecko) Chrome/27.0.1430.0 (Dart) Safari/537.33
Access-Control-Request-Headers: origin, content-type
Accept: */*
Referer: http://127.0.0.1:3030/E:/grole/dart/Clases/Clases/web/out/clases.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: es-ES,es;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
As you can see, it is using the OPTIONS verb instead of POST?
What's going on?
The OPTIONS verb is a preflight request sent by some browsers to check the validity of cross origin requests. It pretty much checks with the server that the Origin(requester) is allowed to make the request for a specified resource. Also, depending on which headers are sent back by the server it lets the browser know which headers, methods, and resources the origin is allowed to request form the server.
The browser sends the OPTIONS request then if the server answers back with the correct headers (CORS headers) allowing the origin to make the request, you should see your POST request go through afterwards.
Note that the CORS headers must be returned on both the OPTIONS response as well as the POST response. This means your server must be able to respond to the options method on the routes you want to access across domains.
This is known as Cross-origin Resource Sharing. Mozilla has some pretty good documentation on the subject. https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
If you have more questions let me know and I'll answer them.
One way to avoid this problem is by sending the request payload without custom headers and using formData to setup your request payload.
How come when I go to almost any website, for example SO, if I open up the console, inject jQuery and send a cross-domain ajax request to a server I have running on my localhost, I don't get any errors as I would have expected? However, if I open up one of the webpages that I have written myself, and which is also running on my localhost (but on a different port from the one used by the server), if I try to send an ajax request from the console I get this message:
XMLHttpRequest cannot load https://localhost:10000/. Request header field My-First-Header is not allowed by Access-Control-Allow-Headers in preflight response.
The ajax request looks like:
$.ajax({
type: 'POST',
url: 'https://localhost:10000',
headers: {
"My-First-Header":"first value",
"My-Second-Header":"second value"
}
})
To be clear, my question is not about how to fix this, but rather why I am even able to make cross-domain requests from most other websites (shouldn't they be not allowed?). Do these sites have some sort of mechanism set up that automatically bypasses the restrictions?
Request headers:
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Cookie:csrftoken=lxe5MaAlb9GC5lPGQpXtSj9HvCP0QhCz; PHPSESSID=uta0nlhlh8r1uimdklmt3v3ho1
Host:localhost:10000
Referer:http://stackoverflow.com/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36
Response headers:
Content-Length:3
Content-Type:text/html
Date:Mon, 16 May 2016 06:29:03 GMT
Server:TwistedWeb/16.0.0
It seems obvious what's going on here: the browser simply handles code typed in the console differently than code run by the page itself. It makes philosophical sense that it would work that way. After all, the point of the Same-Origin Policy is to prevent XSS and CSRF attacks, and if a user opens up their console and sends cross-domain requests, they're just attacking themselves.
On the other hand, it is possible to trick users into performing XSS on themselves. If you go to Facebook and open up the console, Facebook has code that logs a warning message telling ordinary users not to paste unknown code into the console because it could be malicious. Apparently that's a problem they've seen.
This is called as CORS request.
By default all Cross Domain requests are blocked by most of the major browsers.
Most of the portals services that you are able to request cross domain does special settings in Response. If you don't provide those settings at api level then your api will be blocked for cross domain requests.
These Response settings are as follows:
Response Header Need to have access-control-allow-origin attribute.
access-control-allow-origin can specify * for every api service at global level.
access-control-allow-origin can specify specific method name for every api service separately..
After not being able to figure out what was going wrong, I thought that I'd try my luck on here to see if anyone knows what's going on.
I have an angularJS app with a GoLang/Gorilla mux server backend.
The web app is on http://localhost:8888/ and the server, http://localhost:8080/
Basically I have this simple Javascript GET request:
$.get('http://localhost:8080/api/v1'+'/locations/', {borough: "Queens"})
Using inspect element, in the response headers I can see the following:
Content-Length:68
Content-Type:text/html; charset=utf-8
Date:Sun, 17 Apr 2016 20:12:00 GMT
Location:/api/v1/locations?borough=queens
And the following in the console:
XMLHttpRequest cannot load http://localhost:8080/api/v1/locations/? borough=queens. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8888' is therefore not allowed access.
I try the exact same request using Postman and see a 401 with:
Access-Control-Allow-Origin →*
Content-Length →0
Content-Type →text/plain; charset=utf-8
Date →Sun, 17 Apr 2016 19:46:53 GMT
Which is what I expect. For some reason, it appears that my request is not even making it to the server, which does not offer a 301 request. The fact that Postman and the app give completely different responses is perplexing.
I had some issues with CORS but thought I resolved that. The fact that Postman gives me a different result with the Access-Control-Allow-Origin header makes me think this is something else.
I welcome any help.
Edit:
I made the server reply back with the standard Cors parameters. This is what I get now from Postman:
Access-Control-Allow-Headers →Origin, X-Requested-With, Content-Type, Accept, Authorization
Access-Control-Allow-Methods →GET, POST, PUT, DELETE
Access-Control-Allow-Origin →*
Content-Length →0
Content-Type →text/plain; charset=utf-8
Date →Sun, 17 Apr 2016 20:27:31 GMT
Still get the 301 for the JS call...
Edit2: (tried setting Postman call to exact same as network request)
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost:8080
Origin:http://localhost:8888
Referer:http://localhost:8888/root/mainapp/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36
Still get the same 301 from inspect element and expected 401 with Postman. How can it be that in a Restful HTTP context, we have two identical HTTP calls and yet have completely different behavior out of it?!
So basically when I removed the final slash to make it:
from
$.get('http://localhost:8080/api/v1'+'/locations/', {borough: "Queens"})
to
$.get('http://localhost:8080/api/v1'+'/locations', {borough: "Queens"})
This worked!!! I have no bloody idea as to why. If I would love to hear from anyone that may know what happened here and why this works. I'll reiterate- because of the last slash, the request didn't even make it to the server.
This question already has answers here:
CORS & example.com
(3 answers)
Closed 7 years ago.
I don't know why my ajax CORS doesn't work..
ajax
$(document).ready(function(){
var xhr = new XMLHttpRequest();
$.ajax({
url: "SERVER_URL_AND_PARAMETERS",
type:"POST",
beforeSend:function(xhr){
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
xhr.setRequestHeader("Access-Control-Allow-Methods", "GET, POST");
},
dataType:"json",
crossDomain: true,
success:function(data, textStatus, xhr){
alert(data);
},
error:function(xhr,status,error){
alert("code:"+xhr.textStatus+"\n"+"message:"+error.responseText+"\n"+"error:"+error.log);
}
});
});
response headers
Allow:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS
Cache-Control:no-cache="set-cookie, set-cookie2"
Connection:Keep-Alive
Content-Language:ko-KR
Content-Length:0
Content-Type:text/plain
Date:Mon, 02 Nov 2015 07:19:54 GMT
Expires:Thu, 01 Dec 1994 16:00:00 GMT
Keep-Alive:timeout=10, max=100
Set-Cookie:SOME_COOKIES; Expires=Tue, 01-Nov-16 07:19:53 GMT; Path=/
X-UA-Compatible:IE=EmulateIE8, requiresActiveX=true
request headers
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, access-control-allow-headers, access-control-allow-methods, access-control-allow-origin
Access-Control-Request-Method:POST
Connection:keep-alive
Host:SERVER_URL
Origin:http://CLIENT_URL
Referer:http://CLIENT_URL/AND/JSP_FILE_PATH.jsp?lineCd=CODE1&prdtCode=CODE2
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36
chrome error detail
MLHttpRequest cannot load SERVER_URL_AND_PARAMETER Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'CLIENT_URL' is therefore not allowed access.
I don't know what is the problem on my code. I am working on CLIENT_URL side web application.
CORS headers such as "Access-Control-Allow-Origin" MUST be set by the server, not by the client. It is the server that grants CORS access to clients, not the other way around. You can't give yourself CORS access from the browser.
From the MDN section on CORS, here's a descriptive quote:
The Cross-Origin Resource Sharing standard works by adding new HTTP
headers that allow servers to describe the set of origins that are
permitted to read that information using a web browser. Additionally,
for HTTP request methods that can cause side-effects on user data (in
particular, for HTTP methods other than GET, or for POST usage with
certain MIME types), the specification mandates that browsers
"preflight" the request, soliciting supported methods from the server
with an HTTP OPTIONS request method, and then, upon "approval" from
the server, sending the actual request with the actual HTTP request
method. Servers can also notify clients whether "credentials"
(including Cookies and HTTP Authentication data) should be sent with
requests.
In particular, note the part that says "allow servers to describe the set of origins that are permitted to read that information using a web browser".