Only GET working in cross domain API request with django-piston - javascript

I'm not able to do POST/PUT/DELETE cross-domain request on my API using django-piston, I've CORS enabled using this script (based on this):
class CORSResource(Resource):
"""
Piston Resource to enable CORS.
"""
# headers sent in all responses
cors_headers = [
('Access-Control-Allow-Origin', '*'),
('Access-Control-Allow-Headers', 'AUTHORIZATION'),
]
# headers sent in pre-flight responses
preflight_headers = cors_headers + [
('Access-Control-Allow-Methods', '*'),
('Access-Control-Allow-Credentials','true')
]
def __init__(self, handler, authentication=None):
super(CORSResource, self).__init__(handler, authentication)
self.csrf_exempt = getattr(self.handler, 'csrf_exempt', True)
def __call__(self, request, *args, **kwargs):
request_method = request.method.upper()
# intercept OPTIONS method requests
if request_method == "OPTIONS":
# preflight requests don't need a body, just headers
resp = HttpResponse()
# add headers to the empty response
for hk, hv in self.preflight_headers:
resp[hk] = hv
else:
# otherwise, behave as if we called the base Resource
resp = super(CORSResource, self).__call__(request, *args, **kwargs)
# slip in the headers after we get the response
# from the handler
for hk, hv in self.cors_headers:
resp[hk] = hv
return resp
#property
def __name__(self):
return self.__class__.__name__
In the frontend I'm using Backbone with JSONP activated. I don't have any errors, the OPTIONS request works fine then nothing happens. I tried to change the « Access-Control-Allow-Methods » but it doesn't change anything. Any idea ?
Edit:
Here is the request headers of an OPTIONS request:
OPTIONS /api/comments/ HTTP/1.1
Host: apitest.dev:8000
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Origin: http://3l-oauth.dev:1338
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization,content-type
Pragma: no-cache
Cache-Control: no-cache
and the response headers:
HTTP/1.0 200 OK
Date: Sat, 12 May 2012 09:22:56 GMT
Server: WSGIServer/0.1 Python/2.7.3
Access-Control-Allow-Methods: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: AUTHORIZATION
Content-Type: text/html; charset=utf-8
X-Frame-Options: SAMEORIGIN

JSONP is GET only:
You cannot make POST, PUT, or DELETE requests cross-domain. Cross domain JavaScript is facilitated through the use of <script> tags that send requests to your server for dynamic JavaScript. script tags are GET requests only.
However, one of the recommended methods for adjusting to this limitation when dealing with cross-domain JavaScript is to use a method query parameter that you would use in your server-side code to determine how you should handle a specific request.
For instance, if the request was
POST /api/comments/
then you could do this:
/api/comments?method=POST
Under the hood, it's still a GET request, but you can achieve your goal with slight modifications to your API.
When determining the type of request, instead of checking the HTTP Method:
if request_method == "OPTIONS":
Check the request parameter "method" instead:
if request.GET["method"] == "OPTIONS":
JSONP Requests Must return JavaScript:
The other really important point to take note of is that your JSONP requests must all return JavaScript wrapped (or padded) in a function call. Since the requests are made under the hood by script tags that expect JavaScript, your server must return content that the browser understands.
If this doesn't make sense to you or you need more information, there is a great explanation here on how JSONP and script tag remoting works under the hood.

Related

Access-Control-Allow-Originin multiple values with AJAX to PHP on Remote URL (same server)

I know there are a ton of similar posts about this subject, but I have been at this almost full time for two days and tried & read about any possible solution i could find. None worked so I am trying to figure out if any other expert has an idea that might work.
I'm trying to call a PHP script on (fictional) websiteshop.net from websitedojo.com. It's done with an AJAX call and works fine on the native URL.
I'm transferring the program, but want to leave the backend scripts on the native/original URL. I'm getting the error that is well known and widely diuscussed:
Failed to load https://websiteshop.net/cl/ajax-tst.php: The
'Access-Control-Allow-Origin' header contains multiple values
'https://websitedojo.com, *', but only one is allowed. Origin
'https://websitedojo.com' is therefore not allowed access.
Plus, after clikcing the alert box:
Cross-Origin Read Blocking (CORB) blocked cross-origin response
https://websiteshop.net/cl/ajax-tst.php with MIME type
application/json. See
https://www.chromestatus.com/feature/5629709824032768 for more
details.
I have tested so many things by now it is driving me insane. Below the part of an AJAX call, I tried all sorts of variations and combinations here. Whatever is commented, I tried as well without comments of course:
AJAX:
$.ajax({
url: "https://websiteshop.net/cl/ajax_tst.php", // Url to which the request is send
// headers:{
// "Access-Control-Allow-Origin": "*"
// },
type: "POST", // Type of request to be send, called as method
data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
//data: data,
crossOrigin: true,
dataType: 'jsonp',
contentType: false, // The content type used when sending data to the server.
cache: false, // To unable request pages to be cached
processData: false, // To send DOMDocument or non processed data file it is set to false
success: function (data) // A function to be called if request succeeds
{
...
In htaccess I tried all combinations like these and others:
Options -Indexes
Header set Access-Control-Allow-Origin "https://websitedojo.com, *"
#<IfModule mod_headers.c>
# SetEnvIf Origin "http(s)?://(www\.)?(websitedojo.com|other.nl)$" AccessControlAllowOrigin=$0$1
# Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
# Header set Access-Control-Allow-Credentials true
#</IfModule>
In the PHP file itself, I tried these combinations (also without https://):
header_remove('Access-Control-Allow-Origin');
// header('Access-Control-Allow-Origin: "https://websitedojo.com, *');
$allowed=array('https://websitedojo.com','https://www.websitedojo.com', 'https://websiteshop.net','http://localhost','http://127.0.0.1');
$origin=isset($_SERVER['HTTP_ORIGIN'])?$_SERVER['HTTP_ORIGIN']:$_SERVER['HTTP_HOST'];
if(in_array($origin, $allowed)){
header('Access-Control-Allow-Origin: '.$origin);
}else{
exit(0);
}
header('Access-Control-Allow-Methods: POST, OPTIONS, GET, PUT');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Headers: Authorization, X-Requested-With');
header('P3P: CP="NON DSP LAW CUR ADM DEV TAI PSA PSD HIS OUR DEL IND UNI PUR COM NAV INT DEM CNT STA POL HEA PRE LOC IVD SAM IVA OTC"');
header('Access-Control-Max-Age: 1');
This is the latest result from the headers.
Requestheaders:
Host: websiteshop.net
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0
Accept: */*
Accept-Language: nl,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
Referer: https://websitedojo.com/websiteshop/dynamic-and-crazy-engagement/
Content-Type: multipart/form-data; boundary=---------------------------23129260416654
Content-Length: 297094
Origin: https://websitedojo.com
Connection: keep-alive
Response:
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 16 Oct 2018 10:53:37 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.37
Access-Control-Allow-Origin: https://websitedojo.com
Access-Control-Allow-Methods: POST, OPTIONS, GET, PUT
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Authorization, X-Requested-With
P3P: CP="NON DSP LAW CUR ADM DEV TAI PSA PSD HIS OUR DEL IND UNI PUR COM NAV INT DEM CNT STA POL HEA PRE LOC IVD SAM IVA OTC"
Access-Control-Max-Age: 1
Vary: User-Agent
Access-Control-Allow-Origin: *
Content-Encoding: gzip
Are there any none-server related things I can try? Or can I run an SSH command to see my serversettings for the necessary settings?
Ok, solved (with new issues but that's fine).
Apache and Nginx were each setting the same header, my host (thanks Mike) has removed the one from apache so only nginx is setting it now.

Csrf verification failed - Django Rest and Backbone.js [duplicate]

This question already has answers here:
Got CSRF verification failure when while requesting POST through API
(2 answers)
Closed 5 years ago.
I have started going through "Lightweight Django" https://github.com/lightweightdjango to learn more about Django and Client-Side JavaScript. During testing out the LoginView created using Backbone.js I get the Forbidden(403) CSRF verification failed.Request aborted. message, as pointed out in this post: CSRF verification failing in django/backbone.js .
First of all I thought of inserting {% csrf_token %} template tag in the form but when I do this the server is giving me a POST / HTTP/1.1" 405 0 - Method Not Allowed (POST) : / message.
Since the AJAX X-CSRFToken request header is being set using $.ajaxPrefilter(), I can't figure out what the problem is.
When I am using httpie to perform POST requests using the superuser details, everything works just fine as in the following example:
HTTP/1.0 200 OK
Allow: POST, OPTIONS
Content-Type: application/json
Date: Mon, 11 Sep 2017 13:49:49 GMT
Server: WSGIServer/0.2 CPython/3.6.2
Vary: Cookie
X-Frame-Options: SAMEORIGIN
{
"token" : some_value
}
Making use of the console from the "Inspect Element" feature I get the following messages:
Response headers:
Allow: GET, HEAD, OPTIONS
Content-Length: 0
Content-Type: text/html; charset=utf-8
Date: Mon, 11 Sep 2017 14:03:06 GMT
Server: WSGIServer/0.2 CPython/3.6.2
X-Frame-Options: SAMEORIGIN
Request headers:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5
Connection: keep-alive
Content-Length: 116
Content-Type: application/x-www-form-urlencoded
Cookie: csrftoken=some_value
Host: 127.0.0.1:8000
Referer: http://127.0.0.1:8000/
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.0
I don't know if the TemplateView is to blame or I am missing something:
urls.py:
from django.conf.urls import url,include
from django.views.generic import TemplateView
#from django.views.decorators.csrf import ensure_csrf_cookie
from rest_framework.authtoken.views import obtain_auth_token
from board.urls import router
urlpatterns = [
url(r'^api-auth/', obtain_auth_token, name='api-login'),
url(r'^api-root/', include(router.urls)),
url(r'^$', TemplateView.as_view(template_name='board/index.html')),
]
Can someone explain what is actually going on?
Thanks!
Fore every POST request you need to send CSRF token to your django backend in Django weebasite u can fined ajaxSetup for your frontend (backbone.js). Just create new file ajaxSetup.js and past this code.
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function sameOrigin(url) {
// test that a given url is a same-origin URL
// url could be relative or scheme relative or absolute
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (url == origin || url.slice(0, origin.length + 1) == origin +
'/') ||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin +
'/') ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
// Send the token to same-origin, relative URLs only.
// Send the token only if the method warrants CSRF protection
// Using the CSRFToken value acquired earlier
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
You can read about this in django official website CSRF TOKEN

Sending JSON string to cherrypy

I'm trying to send a JSON string from a single HTML (this file is not served by cherrypy) file via Javascript to a cherrpy server.
This is my minimal cherrypy example (followed the "dealing with json" part)
import cherrypy
class HelloJson(object):
#cherrypy.expose
#cherrypy.tools.json_in()
def default(self):
data = cherrypy.request.json
print(data)
return "Hello world!"
if __name__ == '__main__':
cherrypy.config.update({'server.socket_port':1234})
cherrypy.quickstart(HelloJson())
Sending a JSON string via python works gently
>>> requests.post('http://localhost:1234', json=json.dumps({'Hello': 'Json'}))
<Response [200]>
>>>
The cherrypy output prints the json string too
20:59 $ ./HelloJson.py
[24/Aug/2015:20:59:34] ENGINE Listening for SIGTERM.
[24/Aug/2015:20:59:34] ENGINE Listening for SIGUSR1.
[24/Aug/2015:20:59:34] ENGINE Listening for SIGHUP.
[24/Aug/2015:20:59:34] ENGINE Bus STARTING
CherryPy Checker:
The Application mounted at '' has an empty config.
[24/Aug/2015:20:59:34] ENGINE Started monitor thread '_TimeoutMonitor'.
[24/Aug/2015:20:59:34] ENGINE Started monitor thread 'Autoreloader'.
[24/Aug/2015:20:59:34] ENGINE Serving on http://127.0.0.1:1234
[24/Aug/2015:20:59:34] ENGINE Bus STARTED
{"Hello": "Json"}
127.0.0.1 - - [24/Aug/2015:21:00:17] "POST / HTTP/1.1" 200 12 "" "python-requests/2.7.0 CPython/3.4.3 Linux/4.1.5-1-ARCH"
So my single HTML file looks like this
<html>
<head>
<script>
function makeRequest()
{
var insertJSON = { "my_key": "my_value" };
var xmlhttp = new XMLHttpRequest(); // new HttpRequest instance
xmlhttp.open("POST", "http://localhost:1234");
xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xmlhttp.send(JSON.stringify(insertJSON));
}
</script>
</head>
<body>
<form name="frm1" id="yourTextBox" onsubmit="makeRequest()">
<input type="submit" value="Submit">
</form>
</body>
</html>
But this results in an error AttributeError: 'Request' object has no attribute 'json'
[24/Aug/2015:21:10:36] HTTP
Request Headers:
CONNECTION: keep-alive
ACCEPT-LANGUAGE: en-US,en;q=0.5
ACCESS-CONTROL-REQUEST-HEADERS: content-type
ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
USER-AGENT: Mozilla/5.0 (X11; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0
ACCESS-CONTROL-REQUEST-METHOD: POST
ACCEPT-ENCODING: gzip, deflate
PRAGMA: no-cache
CACHE-CONTROL: no-cache
HOST: localhost:1234
Remote-Addr: 127.0.0.1
ORIGIN: null
[24/Aug/2015:21:10:36] HTTP Traceback (most recent call last):
File "/usr/lib/python3.4/site-packages/cherrypy/_cprequest.py", line 670, in respond
response.body = self.handler()
File "/usr/lib/python3.4/site-packages/cherrypy/lib/encoding.py", line 217, in __call__
self.body = self.oldhandler(*args, **kwargs)
File "/usr/lib/python3.4/site-packages/cherrypy/_cpdispatch.py", line 61, in __call__
return self.callable(*self.args, **self.kwargs)
File "./HelloJson.py", line 15, in default
data = cherrypy.request.json
File "/usr/lib/python3.4/site-packages/cherrypy/__init__.py", line 224, in __getattr__
return getattr(child, name)
AttributeError: 'Request' object has no attribute 'json'
127.0.0.1 - - [24/Aug/2015:21:10:36] "OPTIONS / HTTP/1.1" 500 1515 "" "Mozilla/5.0 (X11; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0"
I've no idea what I'm doing wrong.
The OPTIONS request you see is a CORS preflight request, which obviously isn't a JSON request and you see the error. Because you open your file from file:// protocol (or another host), and CherryPy is serving on http://127.0.0.1:1234 you do a cross-domain request, which is subject to Same-Origin Policy.
The simplest way to solve this is to also serve the HTML file by CherryPy (Static content serving). The hard way is to provide proper CORS headers to allow cross domain requests (see this answer)
I agree with saaj's response that the browser sends a CORS preflight request which can be handled in the following manner:
import cherrypy
class HelloJson(object):
#cherrypy.expose
#cherrypy.tools.json_in()
def POST(self):
data = cherrypy.request.json
print(data)
return "Hello world!"
def OPTIONS(self):
cherrypy.response.headers["Access-Control-Allow-Methods"] = "POST, OPTIONS"
cherrypy.response.headers["Access-Control-Allow-Credentials"] = "true"
cherrypy.response.headers["Access-Control-Max-Age"] = "86400"
cherrypy.response.headers[
"Access-Control-Allow-Headers"] = "X-Mobile, Authorization, Origin, X-Requested-With, Content-Type, Accept"
cherrypy.response.headers["Content-Type"] = "application/json; charset=utf-8"
return ''
if __name__ == '__main__':
cherrypy.config.update({
'server.socket_port':1234,
'request.dispatch': cherrypy.dispatch.MethodDispatcher()
})
cherrypy.quickstart(HelloJson(), '/')
This would work because now you have enabled your API backend to listen to browser's OPTIONS call which tells the browser, what are the allowed methods and origins. cherrypy.dispatch.MethodDispatcher() enables you to treat your class as a method dispatcher and thus you can use the class to serve RESTFUL API.

AJAX function w/ Mailgun, getting "ERROR Request header field Authorization is not allowed by Access-Control-Allow-Headers"

I'm working on making an AJAX call that hit the Mailgun API to send email. Documentation on Mailgun says that post requests should be made to "https://api.mailgun.net/v3/domain.com/messages". I've included my api key as specified by mailgun (they instruct to use a username of 'api'). Since this involves CORS, I can't get past the error: Request header field Authorization is not allowed by Access-Control-Allow-Headers.
However, I've inspected the requests/responses in the Network tab and "Access-Control-Allow-Origin" in the response from Mailgun is set to "*"...which should indicate that it should allow it? (See request/response below): I've edited the actual domain and my API key.
Remote Address:104.130.177.23:443
Request URL:https://api.mailgun.net/v3/domain.com/messages
Request Method:OPTIONS
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, authorization
Access-Control-Request-Method:POST
Connection:keep-alive
Host:api.mailgun.net
Origin:null
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36
Response Headersview source
Access-Control-Allow-Headers:Content-Type, x-requested-with
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin:*
Access-Control-Max-Age:600
Allow:POST, OPTIONS
Connection:keep-alive
Content-Length:0
Content-Type:text/html; charset=utf-8
Date:Fri, 20 Mar 2015 19:47:29 GMT
Server:nginx/1.7.9
My code for the ajax call is below, in which I include my credentials in the headers and the domain to where the post is supposed to go. Not sure what's causing this not to work. Is it because I'm testing on local host? I didn't think that would make a difference since the "Access Control Allow Origin:*" in the response header. Any help would be greatly appreciated! Thank you.
function initiateConfirmationEmail(formObj){
var mailgunURL;
mailgunURL = "https://api.mailgun.net/v3/domain.com/messages"
var auth = btoa('api:MYAPIKEYHERE');
$.ajax({
type : 'POST',
cache : false,
headers: {"Authorization": "Basic " + auth},
url : mailgunURL,
data : {"from": "emailhere", "to": "recipient", etc},
success : function(data) {
somefunctionhere();
},
error : function(data) {
console.log('Silent failure.');
}
});
return false;
}
Drazisil is correct above. The response needs to include Access-Control-Allow-Headers: Authorization as you are including that header in your request and Authorization is not a simple header.

Can't specify headers in request in AngularJS

I have 2 parts in my app - Angular frontend and rails server. And because it's different domains, requests doesn't work by default. There are a lot of staff about that, including stack, but it doesn't works for me.
This is my method in angular controller:
$scope.test =->
# transform = (data) ->
# $.param data
$http.post('http://localhost:3000/session/create', 'token=some',
headers:
'Access-Control-Allow-Origin': 'http://localhost:9000',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, X-Requested-With'
# transformRequest: transform
).success (responseData) ->
console.log(responseData)
I commented transform data, there is no difference in server response.
And I configured app (saw this in some post) like that:
.config ["$httpProvider", ($httpProvider) ->
$httpProvider.defaults.useXDomain = true
delete $httpProvider.defaults.headers.common["X-Requested-With"]
]
I guess that makes request not ajax like (but i'm not sure).
But there is no headers in my request. They all in some field Access-Control-Request-Headers:access-control-allow-origin, accept, access-control-allow-headers, access-control-allow-methods, content-type:
Request URL:http://localhost:3000/session/create
Request Method:OPTIONS
Status Code:404 Not Found
Request Headers
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,ru;q=0.6
Access-Control-Request-Headers:access-control-allow-origin, accept, access-control-allow-headers, access-control-allow-methods, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
DNT:1
Host:localhost:3000
Origin:http://localhost:9000
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.8 Safari/537.36
Response Headers
Content-Length:12365
Content-Type:text/html; charset=utf-8
X-Request-Id:2cf4b37b-eb47-432a-ab30-b802b3e33218
X-Runtime:0.030128
Chrome console:
OPTIONS http://localhost:3000/session/create 404 (Not Found) angular.js:6730
OPTIONS http://localhost:3000/session/create No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access. angular.js:6730
XMLHttpRequest cannot load http://localhost:3000/session/create. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access. localhost/:1
Other insignificant information:
On the server:
class ApplicationController < ActionController::Base
before_filter :allow_cross_domain_access
protected
def allow_cross_domain_access
headers['Access-Control-Allow-Origin'] = '*'# http://localhost:9000
headers['Access-Control-Allow-Headers'] = 'GET, POST, PUT, DELETE'
headers['Access-Control-Allow-Methods'] = %w{Origin Accept Content-Type X-Requested-With X-CSRF-Token}.join(',')
headers['Access-Control-Max-Age'] = '1728000'
end
end
Routes is obvious post "session/create". And session controller:
class SessionController < ApplicationController
respond_to :json, :html, :js
def create
respond_with "logged in"
# render nothing: true
end
end
I use latest version of angular 1.2.0.rc-2. this is my project on github
You mix up the request and response headers in your example.
When doing a cross domain request (CORS) and you want to make anything different than a plain GET - so for example a POST or adding custom headers - the browser will first make an OPTIONS request.
This is what you see in your developer console:
OPTIONS http://localhost:3000/session/create 404 (Not Found) angular.js:6730
The server then should add the appropriate headers to the response of the OPTIONS request.
So you can remove the custom headers from the Angular call.
Next you need to make sure that your server/application answers the OPTIONS request, not returning a 404.

Categories

Resources