I got this error when I try to POST a JSON file to my server.
On my server-side, the code is:
@POST
@Path("updatedata")
@Produces("text/plain")
@Consumes("application/json")
public Response UpdateData(String info) {
Gson gson = new Gson();
List<Data> list = gson.fromJson(info, new TypeToken<List<Data>>() {
}.getType());
int is_success = 0;
try {
is_success += trainingdata.updateData(list);
} catch (SQLException e) {
e.printStackTrace();
}
String returnjson = "{\"raw\":\"" + list.size() + "\",\"success\":\"" + is_success + "\"}";
return Response.ok().entity(returnjson).header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Methods", "POST").build();
}
I can update my data successfully through RESTClient - a Chrome Plugin.
But when I build the frontend and try to call the API through javascript, Firefox shows: Cross-Origin Request Blocked: The Same Origin Policy... Chrome shows: XMLHttpRequest cannot load ... No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '...' is therefore not allowed access
I wrote the javascript like this:
var json = JSON.stringify(array);
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://myurl:4080/updatedata", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(json);
xhr.onload = function (e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
alert('hello');
}
}
};
xhr.onerror = function (e) {
console.error(xhr.statusText);
};
Is there any problem with my javascript code?
I deploy my backend code and front-end code on the same machine.
The GET function works successfully.
@GET
@Produces("application/json")
@Path("/{cat_id}")
public Response getAllDataById(@PathParam("cat_id") String cat_id) {
ReviewedFormat result = null;
try {
result = trainingdata.getAllDataById(cat_id);
Gson gson = new Gson();
Type dataListType = new TypeToken<ReviewedFormat>() {
}.getType();
String jsonString = gson.toJson(result, dataListType);
return Response.ok().entity(jsonString).header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Methods", "GET").build();
} catch (SQLException e) {
logger.warn(e.getMessage());
}
return null;
}
Front end:
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://URL:4080/mywebservice/v1/trainingdata/" + cat_id, true);
xhr.onload = function (e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
//console.log(xhr.responseText);
var jsoninfo = xhr.responseText;
var obj = JSON.parse(jsoninfo);
}
}
}
I got this error when I try to POST a JSON file to my server.
On my server-side, the code is:
@POST
@Path("updatedata")
@Produces("text/plain")
@Consumes("application/json")
public Response UpdateData(String info) {
Gson gson = new Gson();
List<Data> list = gson.fromJson(info, new TypeToken<List<Data>>() {
}.getType());
int is_success = 0;
try {
is_success += trainingdata.updateData(list);
} catch (SQLException e) {
e.printStackTrace();
}
String returnjson = "{\"raw\":\"" + list.size() + "\",\"success\":\"" + is_success + "\"}";
return Response.ok().entity(returnjson).header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Methods", "POST").build();
}
I can update my data successfully through RESTClient - a Chrome Plugin.
But when I build the frontend and try to call the API through javascript, Firefox shows: Cross-Origin Request Blocked: The Same Origin Policy... Chrome shows: XMLHttpRequest cannot load ... No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '...' is therefore not allowed access
I wrote the javascript like this:
var json = JSON.stringify(array);
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://myurl:4080/updatedata", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(json);
xhr.onload = function (e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
alert('hello');
}
}
};
xhr.onerror = function (e) {
console.error(xhr.statusText);
};
Is there any problem with my javascript code?
I deploy my backend code and front-end code on the same machine.
The GET function works successfully.
@GET
@Produces("application/json")
@Path("/{cat_id}")
public Response getAllDataById(@PathParam("cat_id") String cat_id) {
ReviewedFormat result = null;
try {
result = trainingdata.getAllDataById(cat_id);
Gson gson = new Gson();
Type dataListType = new TypeToken<ReviewedFormat>() {
}.getType();
String jsonString = gson.toJson(result, dataListType);
return Response.ok().entity(jsonString).header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Methods", "GET").build();
} catch (SQLException e) {
logger.warn(e.getMessage());
}
return null;
}
Front end:
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://URL:4080/mywebservice/v1/trainingdata/" + cat_id, true);
xhr.onload = function (e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
//console.log(xhr.responseText);
var jsoninfo = xhr.responseText;
var obj = JSON.parse(jsoninfo);
}
}
}
Share
Improve this question
edited Mar 31, 2022 at 1:02
xXx
1,1511 gold badge11 silver badges24 bronze badges
asked Nov 12, 2014 at 1:33
Freya RenFreya Ren
2,1647 gold badges29 silver badges40 bronze badges
2
- protocols, domains and ports must match – adeneo Commented Nov 12, 2014 at 1:34
- developer.mozilla.org/en-US/docs/Web/Security/… – epascarello Commented Nov 12, 2014 at 1:37
5 Answers
Reset to default 7CORS prevents issues from occurring with cross-site attacks and forces smart development by not relying on other people's resources (which could die). Its a default security feature on most servers and browsers.
In Apache you can disable CORS by adding a header, IIS and AppEngine work similarly.
Since you are developing locally, your best bet is either XAMPP/WAMPP plus an appropriate header - or simply switch to FireFox.
FireFox does not consider local files under CORS, while most browsers do.
Apache Fix:
Add header ->
Header set Access-Control-Allow-Origin "*"
Reset Server ->
apachectl -t
sudo service apache2 reload
IIS Fix:
Modify web.config in root directory (similar to HTAccess)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
App Engine:
Header Method for Python: self.response.headers.add_header()
class CORSEnabledHandler(webapp.RequestHandler):
def get(self):
self.response.headers.add_header("Access-Control-Allow-Origin", "*")
self.response.headers['Content-Type'] = 'text/csv'
self.response.out.write(self.dump_csv())
For Java: resp.addHeader()
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
resp.addHeader("Access-Control-Allow-Origin", "*");
resp.addHeader("Content-Type", "text/csv");
resp.getWriter().append(csvString);
}
For Go: w.Header().Add()
func doGet(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Access-Control-Allow-Origin", "*")
w.Header().Add("Content-Type", "text/csv")
fmt.Fprintf(w, csvData)
}
CORS issues can be bypassed via JSONP for GET requests if this interested you: http://en.wikipedia.org/wiki/JSONP
This is an issue caused by making a cross domain request in javascript. The browser prevents this for security reasons.
In javascript you can't make requests to a different domain (including different port) by default.
Your options are to enable CORS or use a reverse proxy if you need to send requests to another domain.
It sounds like you have control over the remote resource you're posting to. If that's the case, your remote resource needs to have the following header:
Access-Control-Allow-Origin: http://yourrequestingurl.com
More information here (It looks like someone asked a question like yours already): Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at
You can add header in your Nginx configuration and similarly in other web servers
example
add_header Access-Control-Allow-Origin *;
Thanks for @TGH's hint, I finally solve the problem by adding a web proxy.
Refer to Using a Web Proxy, I create a proxy.php file, which receives Javascript's xmlHttpRequest, gets the postdata and calls the web service API.
<?php
$method = isset($_POST['method']) ? $_POST['method'] : 'POST';
$postData = file_get_contents('php://input');
$url = $envArray['url'] . ':' . $envArray['port'] . '/mywebservice/v1/trainingdata/updatedata';
echo curl($url, $postData, $method);
}
function curl($url = '', $params = '', $method = 'POST'){
if (empty($url)) {
error_log('Curl URL is empty.');
return;
}
$envArray = Settings::getEnvAry();
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_POSTFIELDS, html_entity_decode($params, ENT_QUOTES));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($params)
)
);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$rs = array('status' => $http_status, 'response' => $response);
return json_encode($rs);
}
?>
And in the front end, I call the proxy.php
var xhr = new XMLHttpRequest();
xhr.open("POST", "proxy.php", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(json);
I think this is better for deploying project onto remote box, instead of modifying Apache configuration.