Как определить правильный Accept Content-Type с помощью ExpressJS

Мне трудно отличить вызов ajax от других вызовов в ExpressJS.

Насколько я понимаю, я могу использовать request.accepts('json') для идентификации json-запроса?

Проблема в том, что видимо каждый звонок принимает все!

app.get( '*', function(request, response, next ) {
    console.log('request accepts:')

    if( request.accepts( 'json' ) ){
        console.log( '--> accepts json' )
    }
    if( request.accepts( 'html' ) ){
        console.log( '--> accepts html' )
    }
    if( request.accepts( 'blah' ) ){
        console.log( '--> accepts blah' ) // this does not show up
    }
    if( request.accepts( 'application/json' ) ){
        console.log( '--> accepts json2' )
    }

    next()
} )

Если я просто захожу на страницу, она принимает json и html.

Если я попытаюсь использовать $.getJSON( ... url ... ), он также принимает json и html.

Headers:

Browser: "Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
Ajax: "Accept application/json, text/javascript, */*; q=0.01"

Я не эксперт в заголовках accepts, но кажется, что проблема может заключаться в части */*.

Как я могу определить правильный (или, возможно, первый) тип accept в ExpressJS? В качестве альтернативы: как отличить запрос JSON от обычного посещения страницы?


person Katai    schedule 16.07.2016    source источник
comment
Интересно, зачем вам это нужно в первую очередь. Если вам нужно обслуживать разные типы данных с одного и того же URL-адреса, большинство API используют параметр запроса, например /path/to/server?format=json   -  person charlietfl    schedule 16.07.2016
comment
@charlietfl основная причина этого в том, что существует некоторое промежуточное программное обеспечение, не зависящее от пути (которое вызывается в каждом случае), которое я хотел бы отключить во время вызовов на основе json. Поскольку маршрутизация пути, похоже, происходит позже, я не могу установить для нее флаг (потому что уже слишком поздно). Я вижу 2 варианта: либо сделать промежуточное ПО, которое имитирует маршрутизацию и проверяет, вызывается ли конкретный путь (мех!), либо просто проверяет принятые типы.   -  person Katai    schedule 16.07.2016
comment
предполагая, что у вас есть REST API, который обслуживает только json, вы не можете просто проверить, содержит ли маршрут основной путь для этого API, например "/api/". вообще странная проблема   -  person charlietfl    schedule 16.07.2016
comment
Можно также использовать $.ajaxSetup для установки пользовательского заголовка на основе dataType в обратном вызове beforeSend.   -  person charlietfl    schedule 16.07.2016


Ответы (2)


Почти все запросы GET, сделанные браузером, заканчиваются */*, это означает, что он принимает почти все. Чтобы принять решение, вы можете проверить массив req.accepted. Это выглядит так:

[ { value: 'application/json',
    quality: 1,
    type: 'application',
    subtype: 'json' },
{ value: 'text/html',
     quality: 0.5,
     type: 'text',
     subtype: 'html' } ]

Таким образом, если присутствует JSON, это специальный запрос, в противном случае это простой запрос.

person Boris Siscanu    schedule 16.07.2016

Я нашел решение, которое, кажется, работает, используя массив для accepts():

if( request.accepts( [ 'json', 'html' ] ) == 'json' ) {
    // do something
} else {
    // do something else
}
person Katai    schedule 17.07.2016