Javascript &引用;阻止跨来源请求:同一来源策略“;浏览器中的错误

Javascript &引用;阻止跨来源请求:同一来源策略“;浏览器中的错误,javascript,rest,cors,Javascript,Rest,Cors,我在尝试将json文件发布到服务器时遇到了这个错误 在我的服务器端,代码是: @POST @Path("updatedata") @Produces("text/plain") @Consumes("application/json") public Response UpdateData(String info) { Gson gson = new Gson(); List<Data> list = gson.

我在尝试将json文件发布到服务器时遇到了这个错误

在我的服务器端,代码是:

    @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();
    }
我的javascript代码有问题吗

我在同一台机器上部署后端代码和前端代码

GET函数成功地工作

@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;
}

这是由于在javascript中发出跨域请求而导致的问题。出于安全原因,浏览器会阻止此操作

在javascript中,默认情况下不能向不同的域(包括不同的端口)发出请求


如果您需要向另一个域发送请求,您可以选择启用CORS或使用反向代理。

CORS通过不依赖其他人的资源(可能会死亡)来防止跨站点攻击发生问题,并强制智能开发。它是大多数服务器和浏览器的默认安全功能

在Apache中,您可以通过添加头来禁用CORS,IIS和AppEngine的工作方式类似

因为您是在本地开发的,所以最好的选择是XAMPP/WAMPP加上适当的头,或者干脆切换到FireFox

Firefox不考虑本地文件在CORS下,而大多数浏览器都是。

Apache修复程序

添加标题->

Header set Access-Control-Allow-Origin "*"
重置服务器->

apachectl -t
  • sudo服务apache2重新加载

IIS修复程序:

在根目录中修改web.config(类似于HTAccess)

对于Java:resp.addHeader()

对于Go:w.Header().Add()


如果您对GET请求感兴趣,可以通过JSONP绕过CORS问题:

听起来您可以控制要发布到的远程资源。如果是这种情况,您的远程资源需要具有以下标头:

Access-Control-Allow-Origin: http://yourrequestingurl.com

这里有更多信息(看起来已经有人问了你这样的问题):

谢谢@TGH的提示,我终于通过添加一个web代理解决了这个问题

参考,我创建了一个proxy.php文件,该文件接收Javascript的xmlHttpRequest,获取postdata并调用web服务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);
}
?>

我认为这对于将项目部署到远程机器上更好,而不是修改Apache配置。

您可以在Nginx配置和其他web服务器中添加头

示例


add_头访问控制允许原点*

协议、域和端口必须匹配我将服务器代码和前端代码放在同一台机器上。这应该是一个问题吗?当你提到反向代理时,如果它们托管在不同的域(包括不同的端口)上是不够的。你是说,例如,我创建一个PHP文件来调用我的服务器吗。前端调用这个PHP文件?是的,这是正确的。在你自己的域上创建一个页面,然后调用服务器上的另一个域。他只需要启用CORS。这不是火箭科学。在Apache中,头是最简单的方法。本地计算机只需切换到FireFox for dev。我正在编写一个关于如何执行此操作的writeup,如下所示。大多数情况下,您只能在GET请求中使用JSONP。但你基本上是对的。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
 <system.webServer>
   <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="*" />
     </customHeaders>
   </httpProtocol>
 </system.webServer>
</configuration>
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())
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
  resp.addHeader("Access-Control-Allow-Origin", "*");
  resp.addHeader("Content-Type", "text/csv");
  resp.getWriter().append(csvString);
}
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)
}
Access-Control-Allow-Origin: http://yourrequestingurl.com
<?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);
}
?>
 var xhr = new XMLHttpRequest();
    xhr.open("POST", "proxy.php", true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(json);