$routeProvider: templateUrl requests with X-Requested-With header - ajax

jQuery.ajax() normally sends an X-Requested-With header with XMLHttpRequest set as the content. On the server (in PHP), I usually detect this by testing:
$is_ajax = $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest'
In AngularJS, commonly found in $routeProvider.when(), you can obtain a template from the server with templateUrl: '/path/on/server'.
My problem is that templateUrl requests seem to not set X-Requested-With headers, so there's no way to distinguish templateUrl requests from any other type of request.
Is there any way to get $routeProvider to send X-Requested-With as XMLHttpRequest?
Reference:
$routeProvider Docs - (search templateUrl)
jQuery jqXHR - see jqXHR.setRequestHeader("X-Requested-With", "XMLHttpRequest")
Using Angular v1.1.5 via Google CDN
Update: I found the actual commit where Angular developers removed X-Requested-With from $http.get. Wonder why they would do that?
Update: https://github.com/angular/angular.js/issues/1004 - discussion where header was removed.

Tip of the hat to Zerot in FreeNode's #angularjs
app.config(['$routeProvider', '$httpProvider', function($routeProvider, $httpProvider) {
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
$routeProvider.when('/', {
templateUrl: '/path/on/server',
controller: 'Ctrl'
});
});
Edit: to be more specific, this is the line you need somewhere:
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

Related

Stop sending preflight requests from axios.post

I have my micro-service developed using spring-boot and spring security and frontend is designed on react-hooks.
Now, while I am send some data to my micro-service using axios.post method, it send CORS preflight method i.e. options method because axios by default send content-type as application/json and application.json leads to send options request to server before any other request.
I have tried sending my request with different headers and content types as 'application/x-www-form-urlencoded' also I have used #cross-origin(*) at my server end.
const config = {
headers: {
'Content-Type': 'application/json'
}
}
const response = await axios.post(ps.user_ms_url+ps.user_login,
{
username:values.email,
password:values.password
// headers:{'tokenvalue':'token'}
},
config);
I expect my browser to send only post request to the server, for that I am ready to change my headers as well.
Any help will be appreciated. Thanks in advance!
I found the solution for my query. As I mentioned above, our browser sends preflight request (means options request) before any other request if our request is not simple (here simple means: if request contains content-type : application/json or custom headers etc) and if we are sending this request to some other domain/ URL.
And our axios.post method carries content-type as application/json by default, that's why, my browser was sending multiple requests (means preflight request before any other request).
Now, I have changed my request content-type to application/x-www-form-urlencoded by sending data as params, as shown below:
var params = new URLSearchParams();
params.append('username', values.email);
params.append('password', values.password);
const response = await axios.post(ps.user_ms_url+ps.user_login,
params);
And handling this request at backend using #ModelAttribute annotation (Spring-boot). So, keeping request simple can stop preflight requests.
You can avoid CORS preflight request by proxying the request. Add this in your webpack development config
devServer: {
port: process.env.PORT || 3000,
proxy: {
'/api': {
target: 'http:localhost:8080',
pathRewrite: { '^/api': '' },
changeOrigin: true,
},
},
}
This means your request to /api/users will forwarded to http://localhost:8080/users.
If you are using create-react-app. just add "proxy": "http://localhost:8080" to your package.json. Check more info here
This looks to be server side CORS issue. You have to allow domains to access resources by providing correct response headers.
You can look at adding CORS headers in spring boot. Refer to this link
Hope that helps!!!

CORs error when accessing Square V2 API

I'm making a client-side request out to V2 of the Square API using Vue and Axios. My Vue component is as follows:
import axios from 'axios';
export default {
mounted() {
var instance = axios.create({
baseURL: 'https://connect.squareup.com/v2/',
timeout: 1000,
headers: {
'Authorization': 'Bearer xxxxxxxxxxxxxxxxx',
'Accepts': 'application/json',
'Content-Type': 'application/json'
}
});
instance.get('catalog/list')
.then(function (response) {
console.log(response);
}) ;
}
}
However, when I make that call, I receive the following error:
Failed to load https://connect.squareup.com/v2/catalog/list: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://local-env.dev' is therefore not allowed access. The response had HTTP status code 403.
That error suggests that there is some configuration that has to happen on the Square side, but I saw no opportunity to whitelist domains, etc.
Has anyone come across this error before, regardless of service, and if so, how did you resolve?
I don't think the Square API supports being called from a browser. I used Postman to do an OPTIONS request on https://connect.squareup.com/v2/catalog/list and the response was a NOT_FOUND. The OPTIONS request is needed for proper CORS support.
Plus, if you did this, I would think your auth token would need to be sent to the client -- thus exposing it to everyone. It looks like the Square API is only designed to be called from a server. But that is just based on me skimming the docs a bit. I have no experience using their API.
When doing OAuth authorization request you are not supposed to do it from your application. Create and URL with the parameters and open it in a new browser window or tab, Something like:
const grants='MERCHANT_PROFILE_READ CUSTOMERS_READ CUSTOMERS_WRITE PAYMENTS_READ PAYMENTS_WRITE PAYMENTS_WRITE_ADDITIONAL_RECIPIENTS PAYMENTS_WRITE_IN_PERSON';
const params = new HttpParams()
.set('scope', grants)
.set('client_id', <YourSquareApplicationId>)
.set('state', '1878789');
const requestUrl = `${<squareUrl>}/oauth2/authorize?${params.toString()}`;
window.open(requestUrl, "_blank");
That new window is supposed to ask the end user to login to his account and accept or deny the request.

CORS: Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true

I have a setup involving
Frontend server (Node.js, domain: localhost:3000) <---> Backend (Django, Ajax, domain: localhost:8000)
Browser <-- webapp <-- Node.js (Serve the app)
Browser (webapp) --> Ajax --> Django(Serve ajax POST requests)
Now, my problem here is with CORS setup which the webapp uses to make Ajax calls to the backend server. In chrome, I keep getting
Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.
doesn't work on firefox either.
My Node.js setup is:
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:8000/');
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
};
And in Django I'm using this middleware along with this
The webapp makes requests as such:
$.ajax({
type: "POST",
url: 'http://localhost:8000/blah',
data: {},
xhrFields: {
withCredentials: true
},
crossDomain: true,
dataType: 'json',
success: successHandler
});
So, the request headers that the webapp sends looks like:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: "Origin, X-Requested-With, Content-Type, Accept"
Access-Control-Allow-Methods: 'GET,PUT,POST,DELETE'
Content-Type: application/json
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: csrftoken=***; sessionid="***"
And here's the response header:
Access-Control-Allow-Headers: Content-Type,*
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST,GET,OPTIONS,PUT,DELETE
Content-Type: application/json
Where am I going wrong?!
Edit 1: I've been using chrome --disable-web-security, but now want things to actually work.
Edit 2: Answer:
So, solution for me django-cors-headers config:
CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
'http://localhost:3000' # Here was the problem indeed and it has to be http://localhost:3000, not http://localhost:3000/
)
This is a part of security, you cannot do that. If you want to allow credentials then your Access-Control-Allow-Origin must not use *. You will have to specify the exact protocol + domain + port. For reference see these questions :
Access-Control-Allow-Origin wildcard subdomains, ports and protocols
Cross Origin Resource Sharing with Credentials
Besides * is too permissive and would defeat use of credentials. So set http://localhost:3000 or http://localhost:8000 as the allow origin header.
If you are using CORS middleware and you want to send withCredential boolean true, you can configure CORS like this:
var cors = require('cors');
app.use(cors({credentials: true, origin: 'http://localhost:3000'}));
Expanding on #Renaud idea, cors now provides a very easy way of doing this:
From cors official documentation found here:
"
origin: Configures the Access-Control-Allow-Origin CORS header.
Possible values:
Boolean - set origin to true to reflect the request origin, as defined by req.header('Origin'), or set it to false to disable CORS.
"
Hence we simply do the following:
const app = express();
const corsConfig = {
credentials: true,
origin: true,
};
app.use(cors(corsConfig));
Lastly I think it is worth mentioning that there are use cases where we would want to allow cross origin requests from anyone; for example, when building a public REST API.
try it:
const cors = require('cors')
const corsOptions = {
origin: 'http://localhost:4200',
credentials: true,
}
app.use(cors(corsOptions));
If you are using express you can use the cors package to allow CORS like so instead of writing your middleware;
var express = require('express')
, cors = require('cors')
, app = express();
app.use(cors());
app.get(function(req,res){
res.send('hello');
});
If you want to allow all origins and keep credentials true, this worked for me:
app.use(cors({
origin: function(origin, callback){
return callback(null, true);
},
optionsSuccessStatus: 200,
credentials: true
}));
This works for me in development but I can't advise that in production, it's just a different way of getting the job done that hasn't been mentioned yet but probably not the best. Anyway here goes:
You can get the origin from the request, then use that in the response header. Here's how it looks in express:
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', req.header('origin') );
next();
});
I don't know what that would look like with your python setup but that should be easy to translate.
(Edit) The previously recomended add-on is not available any longer, you may try this other one
For development purposes in Chrome, installing
this add on will get rid of that specific error:
Access to XMLHttpRequest at 'http://192.168.1.42:8080/sockjs-node/info?t=1546163388687'
from origin 'http://localhost:8080' has been blocked by CORS policy: The value of the
'Access-Control-Allow-Origin' header in the response must not be the wildcard '*'
when the request's credentials mode is 'include'. The credentials mode of requests
initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
After installing, make sure you add your url pattern to the Intercepted URLs by clicking on the AddOn's (CORS, green or red) icon and filling the appropriate textbox. An example URL pattern to add here that will work with http://localhost:8080 would be: *://*
Though we have many solutions regarding the cors origin, I think I may add some missing part. Generally using cors middlware in node.js serves maximum purpose like different http methods (get, post, put, delete).
But there are use cases like sending cookie response, we need to enable credentials as true inside the cors middleware Or we can't set cookie. Also there are use cases to give access to all the origin. in that case, we should use,
{credentials: true, origin: true}
For specific origin, we need to specify the origin name,
{credential: true, origin: "http://localhost:3000"}
For multiple origins,
{credential: true, origin: ["http://localhost:3000", "http://localhost:3001" ]}
In some cases we may need multiple origin to be allowed. One use case is allowing developers only. To have this dynamic whitelisting, we may use this kind of function
const whitelist = ['http://developer1.com', 'http://developer2.com']
const corsOptions = {
origin: (origin, callback) => {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error())
}
}
}
Had this problem with angular, using an auth interceptor to edit the header, before the request gets executed. We used an api-token for authentification, so i had credentials enabled. now, it seems it is not neccessary/allowed anymore
#Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
req = req.clone({
//withCredentials: true, //not needed anymore
setHeaders: {
'Content-Type' : 'application/json',
'API-TOKEN' : 'xxx'
},
});
return next.handle(req);
}
Besides that, there is no side effects right now.
CORS ERROR With NETLIFY and HEROKU
Actually, if none of the above solutions worked for you then you might wanna try this.
In my case, the backend was running on Heroku and the frontend was hosted on netlify.
in the .env file, of the frontend, the server_url was written as
REACT_APP_server_url = "https://ci-cd-backend.herokuapp.com"
and in the backend, all my api calls where written as,
app.get('/login', (req, res, err) => {});
So, Only change you need to do is, add /api at the end of the routes,
so, frontend base url will look like,
REACT_APP_server_url = "https://ci-cd-backend.herokuapp.com/api"
and backend apis should be written as,
app.get('/api/login', (req, res, err) => {})
This worked in my case, and I believe this problem is specifically related when the front end is hosted on netlify.

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

jQuery $.ajax(), $.post sending "OPTIONS" as REQUEST_METHOD in Firefox

Having trouble with what I thought was a relatively simple jQuery plugin...
The plugin should fetch data from a php script via ajax to add options to a <select>. The ajax request is pretty generic:
$.ajax({
url: o.url,
type: 'post',
contentType: "application/x-www-form-urlencoded",
data: '{"method":"getStates", "program":"EXPLORE"}',
success: function (data, status) {
console.log("Success!!");
console.log(data);
console.log(status);
},
error: function (xhr, desc, err) {
console.log(xhr);
console.log("Desc: " + desc + "\nErr:" + err);
}
});
This seems to work fine in Safari. In Firefox 3.5, the REQUEST_TYPE on the server is always 'OPTIONS', and the $_POST data does not appear. Apache logs the request as type 'OPTIONS':
::1 - - [08/Jul/2009:11:43:27 -0500] "OPTIONS sitecodes.php HTTP/1.1" 200 46
Why would this ajax call work in Safari, but not Firefox, and how do I fix it for Firefox?
Response Headers
Date: Wed, 08 Jul 2009 21:22:17 GMT
Server:Apache/2.0.59 (Unix) PHP/5.2.6 DAV/2
X-Powered-By: PHP/5.2.6
Content-Length 46
Keep-Alive timeout=15, max=100
Connection Keep-Alive
Content-Type text/html
Request Headers
Host orderform:8888
User-Agent Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5
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
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive 300
Connection keep-alive
Origin http://ux.inetu.act.org
Access-Control-Request-Method POST
Access-Control-Request-Headers x-requested-with
Here is a picture of the Firebug output:
The reason for the error is the same origin policy. It only allows you to do XMLHTTPRequests to your own domain. See if you can use a JSONP callback instead:
$.getJSON( 'http://<url>/api.php?callback=?', function ( data ) { alert ( data ); } );
I used the following code on Django side to interpret the OPTIONS request and to set the required Access-Control headers. After this my cross domain requests from Firefox started working. As said before, the browser first sends the OPTIONS request and then immediately after that the POST/GET
def send_data(request):
if request.method == "OPTIONS":
response = HttpResponse()
response['Access-Control-Allow-Origin'] = '*'
response['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
response['Access-Control-Max-Age'] = 1000
# note that '*' is not valid for Access-Control-Allow-Headers
response['Access-Control-Allow-Headers'] = 'origin, x-csrftoken, content-type, accept'
return response
if request.method == "POST":
# ...
Edit: it seems to be that at least in some cases you also need to add the same Access-Control headers to the actual response. This can be a little bit confusing, since the request seems to succeed, but Firefox does not pass the contents of the response to the Javascript.
This mozilla developer center article describes various cross-domain request scenarios. The article seems to indicate that a POST request with content type of 'application/x-www-form-urlencoded' should be sent as a 'simple request' (with no 'preflight' OPTIONS request). I found , however, that Firefox sent the OPTIONS request, even though my POST was sent with that content type.
I was able to make this work by creating an options request handler on the server, that set the 'Access-Control-Allow-Origin' response header to '*'. You can be more restrictive by setting it to something specific, like 'http://someurl.com'. Also, I have read that, supposedly, you can specify a comma-separated list of multiple origins, but I couldn't get this to work.
Once Firefox receives the response to the OPTIONS request with an acceptable 'Access-Control-Allow-Origin' value, it sends the POST request.
I've fixed this issue using an entirely-Apache based solution. In my vhost / htaccess I put the following block:
# enable cross domain access control
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"
# force apache to return 200 without executing my scripts
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]
You may not need the latter part, depending on what happens when Apache executes your target script. Credit goes to the friendly ServerFault folk for the latter part.
This PHP at the top of the responding script seems to work. (With Firefox 3.6.11. I have not yet done a lot of testing.)
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Max-Age: 1000');
if(array_key_exists('HTTP_ACCESS_CONTROL_REQUEST_HEADERS', $_SERVER)) {
header('Access-Control-Allow-Headers: '
. $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']);
} else {
header('Access-Control-Allow-Headers: *');
}
if("OPTIONS" == $_SERVER['REQUEST_METHOD']) {
exit(0);
}
I had same problem with sending requests to google maps, and solution is quite simple with jQuery 1.5 - for dataType use dataType: "jsonp"
Culprit is preflight request using OPTIONS method
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.
Web specification refer to: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
I resolved the problem by adding following lines in Nginx conf.
location / {
if ($request_method = OPTIONS ) {
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "POST, GET, PUT, UPDATE, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Authorization";
add_header Access-Control-Allow-Credentials "true";
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
location ~ ^/(xxxx)$ {
if ($request_method = OPTIONS) {
rewrite ^(.*)$ / last;
}
}
I was looking through source 1.3.2, when using JSONP, the request is made by building a SCRIPT element dynamically, which gets past the browsers Same-domain policy. Naturally, you can't make a POST request using a SCRIPT element, the browser would fetch the result using GET.
As you are requesting a JSONP call, the SCRIPT element is not generated, because it only does this when the Type of AJAX call is set to GET.
http://dev.jquery.com/ticket/4690
We had a problem like this with ASP.Net. Our IIS was returning an Internal Server Error when trying to execute a jQuery $.post to get some html content due to PageHandlerFactory was restricted to respond only GET,HEAD,POST,DEBUG Verbs. So you can change that restriction adding the verb "OPTIONS" to the list or selecting "All Verbs"
You can modify that in your IIS Manager, selecting your website, then selecting Handler Mappings, double click in your PageHandlerFactory for *.apx files as you need (We use Integrated application pool with framework 4.0). Click on Request Restrictions, then go to Verbs Tabn and apply your modification.
Now our $.post request is working as expected :)
Check if your form's action URL includes the www part of the domain, while the original page you have opened is viewed without www.
Typically done for Canonical Urls..
I struggled for hours before stumbling upon this article and found the hint of Cross Domain.
I seems that if o.url = 'index.php' and this file exists is ok and returning a success message in the console. It returns an error if I use url:http://www.google.com
If doing a post request why not using directly the $.post method:
$.post("test.php", { func: "getNameAndTime" },
function(data){
alert(data.name); // John
console.log(data.time); // 2pm
}, "json");
It is so much simpler.
I have posted a clear example of how to solve this if control the server code of the domain you are POSTing to. This answer is touched on in this thread, but this more clearly explains it IMO.
How do I send a cross-domain POST request via JavaScript?
Solution to this is:
use dataType: json
add &callback=? to your url
this worked on calling Facebook API and with Firefox. Firebug is using GET instead of OPTIONS with the above conditions (both of them).
Another possibility to circumvent the problem is to use a proxy script. That method is described for example here
Can you try this without
contentType:application/x-www-form-urlencoded
Try adding the option:
dataType: "json"
function test_success(page,name,id,divname,str)
{
var dropdownIndex = document.getElementById(name).selectedIndex;
var dropdownValue = document.getElementById(name)[dropdownIndex].value;
var params='&'+id+'='+dropdownValue+'&'+str;
//makerequest_sp(url, params, divid1);
$.ajax({
url: page,
type: "post",
data: params,
// callback handler that will be called on success
success: function(response, textStatus, jqXHR){
// log a message to the console
document.getElementById(divname).innerHTML = response;
var retname = 'n_district';
var dropdownIndex = document.getElementById(retname).selectedIndex;
var dropdownValue = document.getElementById(retname)[dropdownIndex].value;
if(dropdownValue >0)
{
//alert(dropdownValue);
document.getElementById('inputname').value = dropdownValue;
}
else
{
document.getElementById('inputname').value = "00";
}
return;
url2=page2;
var params2 = parrams2+'&';
makerequest_sp(url2, params2, divid2);
}
});
}
I had a similar problem with trying to use the Facebook API.
The only contentType which didn't send the Preflighted request seemed to be just text/plain... not the rest of the parameters mentioned at mozilla here
Why is this the only browser which does this?
Why doesn't Facebook know and accept the preflight request?
FYI: The aforementioned Moz doc suggests X-Lori headers should trigger a Preflighted request ... it doesn't.
You need to do some work on server side. I see you are using PHP on server side, but solution for .NET web application is here:
Cannot set content-type to 'application/json' in jQuery.ajax
Do the same in PHP script and it will work. Simply: At first request browser is asking server if is allowed to send such data with such type and second request is the proper/allowed.
Try to add the following:
dataType: "json",
ContentType: "application/json",
data: JSON.stringify({"method":"getStates", "program":"EXPLORE"}),
I used a proxy url to solve a similar problem when I want to post data to my apache solr hosted in another server. (This may not be the perfect answer but it solves my problem.)
Follow this URL: Using Mode-Rewrite for proxying, I add this line to my httpd.conf:
RewriteRule ^solr/(.*)$ http://ip:8983/solr$1 [P]
Therefore, I can just post data to /solr instead of posting data to http://ip:8983/solr/*. Then it will be posting data in the same origin.
I already have this code handling well my cors situation in php:
header( 'Access-Control-Allow-Origin: '.CMSConfig::ALLOW_DOMAIN );
header( 'Access-Control-Allow-Headers: '.CMSConfig::ALLOW_DOMAIN );
header( 'Access-Control-Allow-Credentials: true' );
And it was working fine locally and remotely, but not for uploads when remote.
Something happen with apache/php OR my code, I didn't bother to search it, when you request OPTIONS it returns my header with cors rules but with 302 result. Therefore my browser doesn't recognise as an acceptable situation.
What I did, based on #Mark McDonald answer, is just put this code after my header:
if( $_SERVER['REQUEST_METHOD'] === 'OPTIONS' )
{
header("HTTP/1.1 202 Accepted");
exit;
}
Now, when requesting OPTIONS it will just send the header and 202 result.
Please be advised:
JSONP supports only the GET request method.
*Send request by firefox:*
$.ajax({
type: 'POST',//<<===
contentType: 'application/json',
url: url,
dataType: "json"//<<=============
...
});
Above request send by OPTIONS(while ==>type: 'POST')!!!!
$.ajax({
type: 'POST',//<<===
contentType: 'application/json',
url: url,
dataType: "jsonp"//<<==============
...
});
But above request send by GET(while ==>type: 'POST')!!!!
When you are in "cross-domain communication" , pay attention and be careful.

Resources