Add CORS header to an http request using Ajax - javascript

I have developed a Restfull application and I'd like to add another web application to consume its services so I make this Ajax call :
$.ajax({
type: "Post",
async: false,
url: "ip_adress/Inviter/api/Account/Register",
data: donne,
headers: { "Access-Control-Allow-Origin:": "*"},
success: function (data) {
console.log(data);
var tab = [];
tab["username"] = username;
tab["password"] = pwd;
var isLogged = Login.CheckCredential(tab, username);
return isLogged;
},
error: function (xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
}
});
I get this exception :
Object {readyState: 0, status: 0, statusText: "SyntaxError: Failed to
execute 'setRequestHeader' …-Origin:' is not a valid HTTP header
field name."} error DOMException: Failed to execute 'setRequestHeader'
on 'XMLHttpRequest': 'Access-Control-Allow-Origin:' is not a valid
HTTP header field name.
So I need to know :
How can I enable the CORS in this situation?
How can I fix my code?

You can't authorize yourself like that. It's a response header; details in the specification. The server you're sending the request to has to send that header back to let the browser know it's okay to allow your page to send an ajax request to that server. There's nothing you can do in your client-side code if the server you're trying to request from doesn't allow your origin.

somehow i redirected to this question to get the solution for my Flask application. Since the server has to send the response back to the header, the CORS has to set in the server side.
In my case i was trying to send the request from
client
http://127.0.0.1:8081/
to
server
http://127.0.0.1:5051
So i set the cors policy to allow the origin in the client side
headers: { "Access-Control-Allow-Origin:": "*"},
and for the server side, flask provides library to allow the cors
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
it actually got resolved the issue

Related

building a local web server and respond data to javascript

I am trying to learn to build a web application, and that application needs data generated from a python script. After googling around. I found this link and it seems that I need to:
write a server side application in Python. Define a URL(route) that runs your script.
in my Javascript code, make an HTTP request to the URL defined in Step 1.
In my java script, I have the following ajax call, I'm not too sure what goes in the url field:
$.ajax({
type: "get",
url: "http://localhost:5000",
cache: false,
async: "asynchronous",
dataType: "text",
success: function (data) {
//console.log(JSON.stringify(data));
console.log("---->" + data);
},
error: function (request, status, error) {
console.log("Error: " + error);
},
});
As for my web server side, I wanted to write it from sockets since I want to learn some socket programing as well, so following another post I wrote my server below, in this server, my goal is to just return a simple string to prove that this works, but ultimately I want to be able to return a json object :
import socket
import threading
import json
import pdb
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 5000))
sock.listen(1)
print("Listening at------>>> ", sock.getsockname())
connections = []
# Reply as HTTP/1.1 server, saying "HTTP OK" (code 200).
response_proto = 'HTTP/1.1'
response_status = '200'
response_status_text = 'OK' # this can be random
res_status = "{} {} {}".format(response_proto, response_status,
response_status_text)
response_body_raw = "hello world"
# Clearly state that connection will be closed after this response,
# and specify length of response body
response_headers = {
'Content-Type': 'text; encoding=utf8',
'Content-Length': len(response_body_raw),
'Connection': 'close',
}
response_headers_raw = ''.join('%s: %s\n' % (k, v) for k, v in
response_headers.items())
def handler(c, a):
global connections
while True:
data = c.recv(1024)
print(data)
for connection in connections:
# sending all this stuff
connection.sendall(res_status.encode('utf-8'))
connection.sendall('\n'.encode('utf-8'))
connection.sendall(response_headers_raw.encode('utf-8'))
# to separate headers from body
connection.sendall('\n'.encode('utf-8'))
connection.sendall(response_body_raw.encode('utf-8'))
if not data:
connections.remove(c)
c.close()
break
while True:
c, a = sock.accept()
print("Connected by------->>>", a)
cThread = threading.Thread(target=handler, args=(c, a))
cThread.daemon = True
cThread.start()
connections.append(c)
when I run my website using VS code live server extension, I get the following errors:
Access to XMLHttpRequest at 'http://localhost:5000/?_=1586356660223' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
GET http://localhost:5000/?_=1586356660223 net::ERR_FAILED
I looked into the No 'Access-Control-Allow-Origin' error, and it seems that I cannot provide url as localhost in my ajax call. if not, then what should I put in the url field if I want to talk to my local server?
Add a Access-Control-Allow-Origin to your response header:
response_headers = {
'Access-Control-Allow-Origin': '*',
...
}
So, as already mentioned in my Comment, I used a Flask server to process the POST-Data sent with Ajax.
Basically, you can set up the server like this:
from flask import Flask, requests
app = Flask(__name__)
#app.route("/", methods=['POST', 'GET'])
def main_page():
return "200"
if __name__ == "__main__":
app.run(debug=True, host='192.169.178.62')
with the host='192.169.178.62', you can specify the IP you want to run your Flask app.
I would suggest you find out your Computers IP, and either use that one to run Flask or use an IP in the same network.
In your AJAX, you need to enter this URL to send the request to.
If anything is not working as it should, feel free to contact me.

CORS Error:Response to preflight request doesn't pass access control check when trying to access Azure Search Api

I am using an ajax put request to perform a merge operation to update a field named DocType for a particular document in azure search index. But getting the error: Failed to load resource: the server responded with a status of 404 (Not Found)
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource
The ajax request I am performing:
var jsonMeta = {
"value": [
{
"#search.action": "merge",
"metadata_storage_path": "*******jkio********",
"DocType": "Test_Merge"
}
]
};
var jsonString = JSON.stringify(jsonMeta);
var url = "https://documentsmartdetect.search.windows.net/indexes/document-smartdetect-index/docs/index?api-version=2017-11-11";
$.ajax({
url: url,
method: 'PUT',
data: JSON.stringify(jsonMeta),
// This is the important part
xhrFields: {
withCredentials: true
},
crossDomain: true,
contentType: 'application/json',
headers: {
"api-key": "***************89**",
},
success: function (response) {
},
error: function (xhr, status) {
alert('error');
}
});
I have also tried using Allowed origin type : all on the azure portal. Need some assistance to fix the CORS issue.
Azure Search does not allow calls from front-end JavaScript, so you cannot do what you want directly.
You will have to call Azure Search from a back-end.
This is actually a serious security problem as well since your Search key is now public within the JavaScript that is sent to all visitors of your web app.

Does a proxy needed for a cross domain Ajax call if no return is expected?

I have a tracking system sending Ajax Call to a remote server in JavaScript. No return values from the server is expected.
This is the Ajax call :
window.onbeforeunload = function () {
$.ajax({
url: "https://remoteURL.com/r/",
type: "get",
async: false,
xhrFields: {
withCredentials: true
},
data: {
tagid: "123"
}
}).done(function () {
console.log("sent");
});
};
Google Chrome show that the request was successfully sent :
The problem is that I didn't get the sent console log, but this error:
Failed to load https://remoteURL.com/r/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://myWebSite.com' is therefore not allowed access.
I have no access to the external server, so I cannot change the header.
If I'm not expecting any return from the remote URL called in Ajax, is this code still functional despite the error thrown in console regarding the cross domain policy ?
Access-Control-Allow-Origin is a restriction made by browsers, so the request was not sent. To do that kind of tracking (without sending the request from a server) you could use ping attribute of <a> like this:
<a href="https://example" ping="https://example/trackpings">
That ping send a void post request to https://example/trackpings in this case.

CORS issue with ASP.net Identity

I am working on an angular.js project with one of my friends, and we are running into a specific CORS (cross origin request) issue. The server is a Microsoft ASP.NET restful API, and I am using angular.js with Node.js.
We enabled CORS on the server side, and are able to get responses for everything else, accept the user login, which we are using ASP.NET Identity with. We always get the same error which I will post bellow, as well as the POST from the Client side. So basically my question is, does any one have an idea on how to fix this? Thanks!
XMLHttpRequest cannot load http://lectioserver.azurewebsites.net/api/v1/accounts/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost' is therefore not allowed access. The response had HTTP status code 400.
function login(username, password) {
var innerconfig = {
url: baseUrl + "/api/v1/accounts/login",
data: {
username: username,
password: password,
grant_type: "password"
},
method: "POST",
headers:
{
'Accept': 'text/json'
}
};
return $http(innerconfig).then(onSuccess, requestFailed);
function onSuccess(results) {
if (results && results.data) {
$rootScope.access_token = results.data.access_token;
return results.data;
}
return null;
}
}
Try to set the content-type in the headers, this might fix the issue
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
This usually happens because app that provides you token starts before CORS initiates.
Fixing it is very easy. You just need to go to IdentityConfig.cs and inside that there is function called as
public static ApplicationUserManager Create
(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
Insert this following line of code there
context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
This will enable CORS for Token request.
But problem is when we do this other normal requests will start throwing error since we have granted access origin * twice. Once in identiy and other in cors.
if you run into this error use this if statement on cors code in identity config you just pasted.
if(context.Request.ContentType == "text/plain")

AngularJS: Cannot send POST request with appropiate CORS headers

I'm creating a web app using AngularJS. To test it, I'm running the app in a NodeJS server, using angular-seed template.
In this app, I need to send a JSON message to another host, via POST request, and get the response, so, I'm using CORS.
My request is done by implementing a service that uses AngularJS http service (I need the level of abstraction that $http provides. So, I don't use $resource).
Here, my code. Please pay attention to the fact that I modify $httpProvider to tell AngularJS to send its requests with the appropriate CORS headers.
angular.module('myapp.services', []).
// Enable AngularJS to send its requests with the appropriate CORS headers
// globally for the whole app:
config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
/**
* Just setting useXDomain to true is not enough. AJAX request are also
* send with the X-Requested-With header, which indicate them as being
* AJAX. Removing the header is necessary, so the server is not
* rejecting the incoming request.
**/
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]).
factory('myService', function($http) {
return {
getResponse: function() {
var exampleCommand = JSON.stringify({"foo": "bar"});
// This really doesn't make a difference
/*
var config = {headers: {
'Access-Control-Allow-Origin':'*',
'Access-Control-Allow-Headers': 'Content-Type, Content-Length, Accept',
'Content-Type': 'application/json'
}
};
*/
//return $http.post(REMOTE_HOST, exampleCommand, config).
return $http.post(REMOTE_HOST, exampleCommand).
success(function(data, status, headers, config) {
console.log(data);
return data;
}).
error(function (data, status, headers, config) {
return {'error': status};
});
}
}
});
The problem is I can't make it work. I always get this error message:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at REMOTE_HOST. This can be fixed by moving the
resource to the same domain or enabling CORS.
But if I do a simple jQuery AJAX call like this:
$.ajax(REMOTE_HOST,
{
dataType: "json",
type: "POST",
data: exampleCommand,
success: function(data) { console.log(data); },
error: function(request, textStatus, errorThrown) { console.log("error " + textStatus + ": " + errorThrown);}
});
It works fine.
So, my questions:
- How do I allow cross-site requests in an AngularJS running under NodeJS?
UPDATE: Thanks to Dayan Moreno Leon's response.
My problem is I need to add cors support to my server. I'm using NodeJS http-server for development and lighttpd for production.
- Why does the simple jQuery POST request work but AngularJS POST request doesn't?
I guess jQuery AJAX requests are cross-domain by default. Not really sure yet.
Many thanks in advance
CORS is not handled on the client but in the server you need to allow CORS on your nodejs app where your angular app is trying to POST. you can try using cors module if you are using express
https://www.npmjs.org/package/cors
other whise you need to check for the options method and return 200 as a response
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
Why does the simple jQuery POST request work but AngularJS POST request doesn't?
jQuery uses simple requests while AngularJS uses preflighted requests
In your angular code you can add set Content-Type to application/x-www-form-urlencoded and encode your data using $.param

Categories

Resources