"阻止跨来源请求:相同来源策略”;浏览器出错
"Cross-Origin Request Blocked: The Same Origin Policy" Error in browser
我在尝试将JSON文件POST到服务器时遇到了这个错误。
在我的服务器端,代码是:
@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();
}
我可以通过RESTClient(一个Chrome插件)成功更新我的数据。
但是当我构建前端并尝试通过javascript调用API时,Firefox显示:跨来源请求被阻止:同源策略。。。Chrome显示:XMLHttpRequest无法加载。。。请求的资源上不存在"Access Control Allow Origin"标头。原点"…"因此不允许访问
我写了这样的javascript:
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);
};
我的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;
}
前端:
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);
}
}
}
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)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
应用程序引擎:
Python的Header方法: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())
对于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);
}
对于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)
}
如果您对此感兴趣,可以通过JSONP为GET请求绕过CORS问题:http://en.wikipedia.org/wiki/JSONP
这是一个由javascript中的跨域请求引起的问题。出于安全原因,浏览器会阻止此操作。
在javascript中,默认情况下不能向不同的域(包括不同的端口)发出请求。
如果您需要向另一个域发送请求,您可以选择启用CORS或使用反向代理。
听起来你可以控制你要发布到的远程资源。如果是这样,你的远程资源需要有以下标题:
Access-Control-Allow-Origin: http://yourrequestingurl.com
更多信息请点击此处(看起来有人已经问了类似您的问题):跨来源请求被阻止:同源策略不允许读取上的远程资源
您可以在Nginx配置中添加标头,也可以在其他web服务器中添加类似的标头
示例
add_header Access-Control-Allow-Origin *;
感谢@TGH的提示,我终于通过添加web代理解决了这个问题。
参考使用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);
}
?>
在前端,我调用proxy.php
var xhr = new XMLHttpRequest();
xhr.open("POST", "proxy.php", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(json);
我认为这更适合将项目部署到远程盒子上,而不是修改Apache配置。
- 访问布局信息是否也会导致浏览器重排
- 内部分区字体大小获胜'调整浏览器窗口大小时不会随媒体查询而更改
- 如何使用phaser使html5游戏在移动设备浏览器上运行
- 有时数据是't显示在浏览器中
- 使图像在单击时展开到不大于浏览器
- fetch() 函数未在 Ubuntu Chromium 浏览器上定义
- 不同浏览器中的空白字符正则表达式行为
- 在Windows 10中自动执行例行程序(主要与浏览器交互)
- Windows形成web浏览器控件和Javascript更改的DOM
- 如何临时暂停浏览器渲染,然后恢复整个页面
- 使用angularjs向浏览器发送servlet响应(下载功能)
- 如果所有浏览器都使用同源策略,CSRF 攻击如何工作?
- 浏览器实现同源策略的方式是否存在实质性差异
- 如何在浏览器 JS 控制台中包含脚本时覆盖内容安全策略
- "阻止跨来源请求:相同来源策略”;浏览器出错
- 浏览器安全策略如何使用XMLHttpRequest
- 浏览器多人网络策略-这似乎是一个可行的解决方案
- 在这种情况下,禁用浏览器的同源策略是可以接受的
- 使用浏览器插件规避同源策略
- 如果web浏览器用户修改Javascript并执行它(例如从控制台),它是否违反同源策略?