"Cross-Origin Request Blocked: The Same Origin Policy" Error in browser
Solution 1
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 receive Javascript's xmlHttpRequest, get the postdata and call 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 deploy project onto remote box, instead of modifying Apache configuration.
Solution 2
CORS 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
Solution 3
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.
Freya Ren
Updated on January 04, 2020Comments
-
Freya Ren over 4 years
I got this error when I try to POST 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 jaascript, 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 in 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); } } }