"Cross-Origin Request Blocked: The Same Origin Policy" Error in browser

22,582

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.

Share:
22,582
Freya Ren
Author by

Freya Ren

Updated on January 04, 2020

Comments

  • Freya Ren
    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);
            }
         }
    }