![](/img/trans.png)
[英]Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource a
[英]“Cross-Origin Request Blocked: The Same Origin Policy” Error in browser
當我嘗試將 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();
}
我可以通過 RESTClient - Chrome 插件成功更新我的數據。
但是當我構建前端並嘗試通過 jaascript 調用 API 時,Firefox 顯示:跨域請求被阻止:同源策略...... Chrome 顯示:XMLHttpRequest 無法加載......沒有'Access-Control-Allow-Origin ' 請求的資源上存在標頭。 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 下的本地文件,而大多數瀏覽器會考慮。
阿帕奇修復:
添加標題->
Header set Access-Control-Allow-Origin "*"
重置服務器 ->
apachectl -t
須藤服務 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 的頭方法: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)
}
如果您對 GET 請求感興趣,可以通過 JSONP 繞過 CORS 問題: http : //en.wikipedia.org/wiki/JSONP
這是由在 javascript 中進行跨域請求引起的問題。 出於安全原因,瀏覽器會阻止這種情況。
在 javascript 中,默認情況下您不能向不同的域(包括不同的端口)發出請求。
如果您需要向另一個域發送請求,您可以選擇啟用 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);
}
?>
在前端,我調用了 proxy.php
var xhr = new XMLHttpRequest();
xhr.open("POST", "proxy.php", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(json);
我認為這更適合將項目部署到遠程框,而不是修改 Apache 配置。
您可以在 Nginx 配置中添加標頭,並在其他 Web 服務器中類似
例子
add_header Access-Control-Allow-Origin *;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.