fetch()不发送头文件?

时间:2017-08-09 13:08:00

标签: javascript http post cors fetch-api

我从浏览器发送这样的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标头。

有什么问题?

编辑1

因此,在Chrome中使用开发工具时,检查了浏览器是否发送了AuthorizationX-My-Custom-Header标头...现在的问题是:为什么?我该如何解决?

编辑2

有关我的应用的更多信息:这是React应用。我已经禁用了服务人员。我尝试创建Authorization并使用Request专门添加标头。标题仍然不会发送。

5 个答案:

答案 0 :(得分:63)

same-origin policy限制网页可以从其他来源发送到资源的请求类型。

no-cors mode中,浏览器仅限于发送“简单”请求 - 仅包含safelisted methodssafelisted headers的请求。

要发送包含AuthorizationX-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-urlencodedmultipart/form-datatext/plain

这就是为什么只发送了Content-Type标题,而不是X-My-Custom-HeaderAuthorization

答案 2 :(得分:3)

你能试试吗?

fetch(serverEndpoint, {  
  credentials: 'include'  
})

参考。 https://developers.google.com/web/updates/2015/03/introduction-to-fetch#sending_credentials_with_a_fetch_request

答案 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()

        }
    }