我从浏览器发送这样的POST请求:
private void startSignalR() {
Platform.loadPlatformComponent(new AndroidPlatformComponent());
mInstance.setmHubConnection(getApplicationContext());
mInstance.setHubProxy();
ClientTransport clientTransport = new ServerSentEventsTransport(mInstance.mHubConnection.getLogger());
signalRFuture = mInstance.mHubConnection.start(clientTransport);
try {
signalRFuture.get();
} catch (InterruptedException | ExecutionException e) {
SharedPrefUtil.clearAllSharedPreferences(getApplicationContext());
Toast.makeText(getApplicationContext(), getString(R.string.wrong_server), Toast.LENGTH_LONG).show();
Log.e("SimpleSignalR", e.toString());
return;
}
mInstance.mHubConnection.error(new ErrorCallback() {
@Override
public void onError(Throwable error) {
error.printStackTrace();
}
});
// Subscribe to the connected event
mInstance.mHubConnection.connected(new Runnable() {
@Override
public void run() {
System.out.println("CONNECTED");
}
});
mInstance.mHubConnection.reconnected(new Runnable() {
@Override
public void run() {
System.out.println("RECONNECTED");
}
});
// Subscribe to the closed event
mInstance.mHubConnection.closed(new Runnable() {
@Override
public void run() {
System.out.println("DISCONNECTED");
}
});
mInstance.mHubProxy.on(SignalRConstant.CLIENT_METHOD_BROADAST_MESSAGE,
new SubscriptionHandler2<String, Object>() {
@Override
public void run(final String msg, final Object data) {
if (msg != null && data != null && !data.equals("")) {
Intent intent = new Intent();
intent.setAction(MY_ACTION);
intent.putExtra("CAPTION", msg);
if(msg.equals(SignalRConstant.CAPTION_LOGINPASS))
{
Gson gson = new GsonBuilder().setDateFormat(AppConstant.DATE_FORMAT).create();
intent.putExtra("DATA", gson.toJson(data));
}else{
intent.putExtra("DATA", data.toString());
}
sendBroadcast(intent);
}
}
}
, String.class, Object.class);
}
当请求到达我的后端时,它不包含fetch(serverEndpoint, {
method: 'POST',
mode: 'no-cors', // this is to prevent browser from sending 'OPTIONS' method request first
redirect: 'follow',
headers: new Headers({
'Content-Type': 'text/plain',
'X-My-Custom-Header': 'value-v',
'Authorization': 'Bearer ' + token,
}),
body: companyName
})
或X-My-Custom-Header
标头。
我的后端是Firebase的Google Cloud功能(基本上只是Node.js端点),如下所示:
Authorization
Google Cloud for Firebase功能的控制台日志不包含任何exports.createCompany = functions.https.onRequest((req, res) => {
let headers = ['Headers: ']
for (let header in req.headers) {
headers.push(`${header} : ${req.headers[header]}`)
}
console.log(headers)
...
}
或X-My-Custom-Header
标头。
有什么问题?
因此,在Chrome中使用开发工具时,检查了浏览器是否发送了Authorization
和X-My-Custom-Header
标头...现在的问题是:为什么?我该如何解决?
有关我的应用的更多信息:这是React应用。我已经禁用了服务人员。我尝试创建Authorization
并使用Request
专门添加标头。标题仍然不会发送。
答案 0 :(得分:63)
same-origin policy限制网页可以从其他来源发送到资源的请求类型。
在no-cors
mode中,浏览器仅限于发送“简单”请求 - 仅包含safelisted methods和safelisted headers的请求。
要发送包含Authorization
和X-My-Custom-Header
标题的跨源请求,您必须放弃no-cors
模式并支持预检请求(OPTIONS
)。
“简单”和“非简单”请求之间的区别是出于历史原因。网页总是可以通过各种方式(例如创建和提交表单)执行一些跨源请求,因此当Web浏览器引入了发送跨源请求(cross-origin resource sharing或CORS)的原则方法时,它是决定这些“简单”请求可以免于预检OPTIONS
检查。
答案 1 :(得分:12)
首先:使用对象代替new Headers(..)
:
fetch('www.example.net', {
method: 'POST',
headers: {
'Content-Type': 'text/plain',
'X-My-Custom-Header': 'value-v',
'Authorization': 'Bearer ' + token,
}
});
其次:很高兴知道,标题会被fetch
小写!!
Thridly :no-cors
模式限制使用标头到此白名单:
Accept
Accept-Language
Content-Language
Content-Type
,其值为(application/x-www-form-urlencoded
,multipart/form-data
,text/plain
)这就是为什么只发送了Content-Type
标题,而不是X-My-Custom-Header
或Authorization
。
答案 2 :(得分:3)
你能试试吗?
fetch(serverEndpoint, {
credentials: 'include'
})
答案 3 :(得分:0)
1st:当你在exports.createCompany函数中调用标题时,你有let headers = ['Headers: ']
,其中包含大写H
而不是小写h
,这可能会导致错误。你在标题中的标记后面也有一个逗号,它不应该存在。
第二:每当我在反应原生中使用获取请求时,header:
都不需要new Headers
。
试试这个:fetch(serverEndpoint, {
method: 'POST',
mode: 'no-cors',
redirect: 'follow',
headers:{
'Content-Type': 'text/plain',
'X-My-Custom-Header': 'value-v',
'Authorization': 'Bearer ' + token
},
body: companyName
})
答案 4 :(得分:0)
我也有同样的问题。我通过从javascript中删除“ no-cors”并在服务器端Spring Boot中添加以下内容来解决了该问题。
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity httpSecurity) throws Exception {
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
}
}