rnd*_*gen 7 javascript c++ cross-domain cors casablanca
我正在使用来自Microsoft C++ REST SDK 1.3.1的web :: http :: experimental :: listener :: http_listener运行HTTP服务器,并尝试将HTML和Javascript编写为客户端以与服务器进行交互.
几乎毫不奇怪我得到了...... Cross-Origin Request Blocked:同源策略禁止读取远程资源......(原因:CORS标题'Access-Control-Allow-Origin'丢失).
如何 在http侦听器端(在c ++代码中)放置Access-Control-Allow-Origin:*?
是否可以在C++ REST 1.3.1中使用?除了JSONP之外还有解决方法吗?
服务器
#include <cpprest/http_listener.h>
#include <cpprest/json.h>
using namespace web;
using namespace web::http;
using namespace web::http::experimental::listener;
http_listener httpSrv;
httpSrv->support(methods::GET, handle_get);
void handle_get(http_request request)
{
const json::value response;
request.reply(status_codes::OK, response);
}
Run Code Online (Sandbox Code Playgroud)
使用jQuery v1.12.4的客户端客户端(受限于jQuery UI v1.12.0)
$("button").click(function () {
$.get(rest_url, function(data, status){
console.log(status);
console.log(data);
});
});
Run Code Online (Sandbox Code Playgroud)
-----------------更新-----------------------
从答案解决
服务器
http_listener httpSrv;
httpSrv.support(methods::GET, handle_get);
httpSrv.support(methods::POST, handle_post);
httpSrv.support(methods::OPTIONS, handle_options);
httpSrv.open().wait();
//...........
void handle_options(http_request request)
{
http_response response(status_codes::OK);
response.headers().add(U("Allow"), U("GET, POST, OPTIONS"));
response.headers().add(U("Access-Control-Allow-Origin"), U("*"));
response.headers().add(U("Access-Control-Allow-Methods"), U("GET, POST, OPTIONS"));
response.headers().add(U("Access-Control-Allow-Headers"), U("Content-Type"));
request.reply(response);
}
void handle_get(http_request request)
{
request.reply(status_codes::OK, ...);
}
void handle_post(http_request request)
{
json::value jsonResponse;
request
.extract_json()
.then([&jsonResponse](pplx::task<json::value> task)
{
jsonResponse = process_request(task.get());
})
.wait();
http_response response(status_codes::OK);
response.headers().add(U("Access-Control-Allow-Origin"), U("*"));
response.set_body(jsonResponse);
request.reply(response);
}
Run Code Online (Sandbox Code Playgroud)
客户
function requestREST(request/*json*/,onSuccess/*callback with json response*/) {
$.ajax({
type: "POST",
url: "...",
data: JSON.stringify(request),
dataType: 'json',
crossDomain: true,
contentType: "application/json",
success: function (response) {
onSuccess(response);
},
timeout:3000,
statusCode: {
400: function (response) {
alert('Not working!');
},
0: function (response) {
alert('Not working!');
}
}
});
Run Code Online (Sandbox Code Playgroud)
要在服务器端(C++)添加标头,您需要修改用于发送响应的代码.
目前,你正在使用:
request.reply(status_codes::OK, response);
Run Code Online (Sandbox Code Playgroud)
不是在单行中进行,而是从空响应开始自己编写响应,添加所需的标题,设置实际的主体,然后将响应发送回客户端.
要构造一个空响应,我们可以使用以下函数:
web::http::http_response::http_response(http::status_code code)
Run Code Online (Sandbox Code Playgroud)
如文档中所述,它将使用给定的状态代码构建响应,没有标题,也没有正文.
要访问响应的标头,我们可以使用以下函数:
web::http::http_response::headers()
Run Code Online (Sandbox Code Playgroud)
返回的对象将是包含函数的http_headers类型:add
web::http::http_headers::add(const key_type &name, const _t1 &value)
Run Code Online (Sandbox Code Playgroud)
如果为标题提供了名称和值,则此函数将为响应添加标头.
设置标题后,剩下要设置的唯一内容是正文.为此,响应具有以下set_body功能:
web::http::http_response::set_body(const json::value &body_data)
Run Code Online (Sandbox Code Playgroud)
最后,完整的代码替换你的单行代码以创建一个空响应,设置标题和正文然后将其发送回来看起来像:
http_response response(status_codes::OK);
response.headers().add(U("Access-Control-Allow-Origin"), U("*"));
response.set_body(jsonResponse);
request.reply(response);
Run Code Online (Sandbox Code Playgroud)
请注意,在代码的最后部分,我正在使用U宏来创建目标平台类型的字符串文字.您可以U在C++ Rest SDK FAQ中找到有关此宏的更多信息.
关于使用OPTIONHTTP动词的预检请求,这些情况在这种情况下是预期的.默认情况下,C++ REST SDK包含这些请求的默认实现.可以在源代码中检查默认实现:
void details::http_listener_impl::handle_options(http_request message)
{
http_response response(status_codes::OK);
response.headers().add(U("Allow"), get_supported_methods());
message.reply(response);
}
Run Code Online (Sandbox Code Playgroud)
它基本上返回一个200状态代码并添加服务器可以处理的受支持方法的列表.
如果你想覆盖默认实现,例如通过增加像预检要求使用一些特定的标题Access-Control-Allow-Methods或Access-Control-Allow-Headers,你需要像你这样的添加特定的处理程序GET和POST要求使用:
web::http::experimental::listener::http_listener::support(const http::method &method, const std::function< void(http_request)> &handler)
Run Code Online (Sandbox Code Playgroud)
使用通用处理程序来处理OPTION请求是不可能的:
web::http::experimental::listener::http_listener::support(const std::function<void(http_request)> &handler)
Run Code Online (Sandbox Code Playgroud)
如果我们看一下源代码,我们不能使用通用处理程序的原因是,如果一个方法没有特定的处理程序并且正在使用OPTIONHTTP动词(或TRACE),那么默认的处理程序由将调用C++ REST SDK:
// Specific method handler takes priority over general.
const method &mtd = msg.method();
if(m_supported_methods.count(mtd))
{
m_supported_methods[mtd](msg);
}
else if(mtd == methods::OPTIONS)
{
handle_options(msg);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2355 次 |
| 最近记录: |