Ajax nie chce wysłać mi zapytanie typu PUT

0

Chcę wysłać do kontrolera nowy e-mail podany przez użytkownika za pomocą ajaxa

$.ajax({
            type: 'PUT',
            url: '/changeEmail?',
            data: {
                email: function() {
                    return $('#email').val();
                }
            },
            success: function(result) {
                console.log('function');
                if(result === true) {
                    console.log("true");
                } else {
                    console.log("false");
                }
            }
        });

do kontrolera(przykładowy kod)

@PutMapping("/changeEmail")
    public boolean changeEmail(
            @RequestParam("email") String email
    ) {
        System.out.println("email: " + email);

        return true;
    }

Jednak podczas wysyłki konsola przeglądarki wyrzuca mi

jquery-3.2.1.min.js:4 PUT http://localhost:8080/signIn net::ERR_TOO_MANY_REDIRECTS

Ajax próbuje wysłać dane na całkiem inny adres, niż ten który podałem w ajaxie.
W ajaxie podałem

/changeEmail

a on próbuje mi wysłać na

/signIn

O co tu chodzi? Taki jest rezultat https://zapodaj.net/f1b8ed0b2a16b.png.html Ajax nie potrafi obsłużyć 'zapytania' typu PUT i próbuje zwrócić domyślną stronę na którą przekierowuje zawsze po wpisaniu błędnego URL.

EDIT: Jest to problem ajaxa, ponieważ zmodyfikowałem kod w taki sposób, aby forma była wysyłana bezpośrednio(bez javascript) i wtedy działa. Ajax nie potrafi wywoływać innych kontrolerów niż typy GET i POST. Prawdopodobnie trzeba coś skonfigurować.

0

Pewnie masz spring security i jest wszystko poza GET wymaga logowania

0

Mam pewien trop. Otóż zauważyłem, że dane nie są wysyłanie jako 'query parameter', ale jako 'form data'. Przez co nie mogę użyć RequestParam. Muszę zastosować RequestBody(tak mi się wydaje).
Stworzyłem do tego dto

public class ChangeEmailDTO {
    @Getter @Setter private String email;
}

a kontroler zmodyfikowałem w ten sposób

@PutMapping("/changeEmail")
    public boolean changeEmail(
            @ReuqestBody ChangeEmailDTO changeEmailDTO
    ) {
        System.out.println("email: " + changeEmailDTO.getEmail());

        return true;
    }

i wysyłka

$.ajax({
            type: 'PUT',
            url: '/changeEmail',
            data: {
                email: $('#email').val()
            },
            success: function (result) {
                console.log('function');
            }
        });

Jednak dalej nie działa. No nie mam pojęci jak to naprawić.

1

Nawet na zalogowanym użytkowniku spring zablokuje PUT, POST i DELETE. Przesyłasz CSRF? Spróbuj wyłączyć sprawdzanie csrf i sprawdź czy zadziała.

http.csrf().disable();
0

Wyłączyłem csrf() i teraz coś się zaczęło dziać, lecz wali błędami

2017-07-26 21:07:15.465 DEBUG 3760 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-07-26 21:07:15.465 DEBUG 3760 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet        : Successfully completed request
2017-07-26 21:07:15.499 DEBUG 3760 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing PUT request for [/changeEmail]
2017-07-26 21:07:15.501 DEBUG 3760 --- [nio-8080-exec-7] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /changeEmail
2017-07-26 21:07:15.505 DEBUG 3760 --- [nio-8080-exec-7] .m.m.a.ExceptionHandlerExceptionResolver : Resolving exception from handler [null]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
2017-07-26 21:07:15.506 DEBUG 3760 --- [nio-8080-exec-7] .w.s.m.a.ResponseStatusExceptionResolver : Resolving exception from handler [null]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
2017-07-26 21:07:15.506 DEBUG 3760 --- [nio-8080-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolving exception from handler [null]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
2017-07-26 21:07:15.508 DEBUG 3760 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-07-26 21:07:15.508 DEBUG 3760 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : Successfully completed request
2017-07-26 21:07:15.509 DEBUG 3760 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing PUT request for [/error]
2017-07-26 21:07:15.510 DEBUG 3760 --- [nio-8080-exec-7] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
2017-07-26 21:07:15.511 DEBUG 3760 --- [nio-8080-exec-7] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView com.movie.database.app.controller.error.PageNotFoundController.showPageError()]
2017-07-26 21:07:15.526 DEBUG 3760 --- [nio-8080-exec-7] o.s.web.cors.DefaultCorsProcessor        : Skip CORS processing: request is from same origin
here
2017-07-26 21:07:15.527 DEBUG 3760 --- [nio-8080-exec-7] o.s.w.s.v.ContentNegotiatingViewResolver : Requested media types are [*/*] based on Accept header types and producible media types [*/*])
2017-07-26 21:07:15.528 DEBUG 3760 --- [nio-8080-exec-7] o.s.w.servlet.view.BeanNameViewResolver  : No matching bean found for view name 'redirect:/signIn'
2017-07-26 21:07:15.528 DEBUG 3760 --- [nio-8080-exec-7] o.s.w.s.v.ContentNegotiatingViewResolver : Returning redirect view [org.springframework.web.servlet.view.RedirectView: unnamed; URL [/signIn]]
2017-07-26 21:07:15.528 DEBUG 3760 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : Rendering view [org.springframework.web.servlet.view.RedirectView: unnamed; URL [/signIn]] in DispatcherServlet with name 'dispatcherServlet'
2017-07-26 21:07:15.530 DEBUG 3760 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : Successfully completed request
2017-07-26 21:07:15.534 DEBUG 3760 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing PUT request for [/signIn]
2017-07-26 21:07:15.535 DEBUG 3760 --- [nio-8080-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /signIn
2017-07-26 21:07:15.536 DEBUG 3760 --- [nio-8080-exec-9] .m.m.a.ExceptionHandlerExceptionResolver : Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PUT' not supported
2017-07-26 21:07:15.536 DEBUG 3760 --- [nio-8080-exec-9] .w.s.m.a.ResponseStatusExceptionResolver : Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PUT' not supported
2017-07-26 21:07:15.536 DEBUG 3760 --- [nio-8080-exec-9] .w.s.m.s.DefaultHandlerExceptionResolver : Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PUT' not supported
2017-07-26 21:07:15.536  WARN 3760 --- [nio-8080-exec-9] o.s.web.servlet.PageNotFound             : Request method 'PUT' not supported
2017-07-26 21:07:15.536 DEBUG 3760 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-07-26 21:07:15.536 DEBUG 3760 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet        : Successfully completed request
2017-07-26 21:07:15.537 DEBUG 3760 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing PUT request for [/error]
2017-07-26 21:07:15.538 DEBUG 3760 --- [nio-8080-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
2017-07-26 21:07:15.539 DEBUG 3760 --- [nio-8080-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView com.movie.database.app.controller.error.PageNotFoundController.showPageError()]
2017-07-26 21:07:15.539 DEBUG 3760 --- [nio-8080-exec-9] o.s.web.cors.DefaultCorsProcessor        : Skip CORS processing: request is from same origin

Dodatkowo zmieniłem, ze ajax wysyła json

data: {
                email: JSON.stringify($('#email').val())
            }

a kontroler przyjmuje

@PutMapping(value = "/changeEmail", consumes = MediaType.APPLICATION_JSON_VALUE)
1

Wg tego stacktrace'a to spring otrzymuje content type:

application/x-www-form-urlencoded;charset=UTF-8

W ajaxie nic nie zmieniłeś (tzn zmieniłeś sam obiekt ale nie o to chodzi). Dodaj do ajaxa:

contentType: "application/json"

Czyli wyjdzie coś takiego:

$.ajax({
    type: "PUT",
    contentType: "application/json",
    url: 'http://localhost:8080/Test',
    data: data,
    dataType: "json",
...
});
0

Po 5 dniach walki udało mi się wysłać bezproblemowo zapytanie PUT do ajaxa. Wyłączyłem scrf() w Spring Security, zmodyfikowałem lekko kod w innych miejscach i działa. Jednak trapi mnie to scrf(). Ponieważ dla bezpieczeństwa chcę używam w aplikacji scrf(), więc zostawiam włączone, a z włączonym nie jestem w stanie wysyłać innych zapytań niż GET. Oczywiście mogę ustawić ignorancję dla określonych adresów stron, jednak gdy użytkownik jest zalogowany i zacznę tworzyć dla niektórych stron ignorancję, to może mieć złe skutki. Nie ma na to jakiegoś innego sposobu, oprócz wyłączenia csrf()?

1 użytkowników online, w tym zalogowanych: 0, gości: 1