odbieranie i przetwarzanie JSON w jQuery - REST w javie

0

witam
chciałbym spytać o taką rzecz, w JavaScripcie i jQuery jestem stosunkowo nowy, szczególnie w tym drugim. Stworzyłem jakiś prosty REST w Springu (java) i url:

http://localhost:8080/main/users

Zwraca mi bardzo prostego JSON'a:

{"name":"Maciej","lastname":"NowyJedenUser"}
(wcześniej dałem też więcej tych obiektów (bo w Springu mam to jako obiekt User z polem name i lastname) ale zmieniłem na 1 żeby było na początek prościej :P)

I teraz chciałbym przez jQuery/javascript (nie wiem co będzie bardziej "na topie") te dane jakos zebrać i wrzucić do obiektu javascriptowego zeby potem wyswietlic chocby liste użytkowników zwróconą z JSONa w tabeli na stronie.
Robie coś takiego:

<!DOCTYPE html>
<html>
<head>
    <title>JSON Parsing</title>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.0.min.js"></script>
</head>
<body>
<script>
    $(document).ready(function(){
        $.ajax({
            url: 'http://localhost:8080/main/users',
            dataType: "application/json",
            success: (function(data){
                $('#tabela').append('<tr><td>' + data.name + '</td><td>' + data.lastame + '</td></tr>');
            })

        });
    });

</script>
<p id="click">click here</p>
<table id="tabela" style="border: 1px solid black;">
        <tr><td>Test</td></tr>
</table>


</body>
</html>

Z moich obserwacji wynika ze "success:" się w ogóle nie wykonuje.
W chrome pod F12 mam coś takiego: (po otwieraniu strony z poziomu phpStorm)

XMLHttpRequest cannot load http://localhost:8080/main/users. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

Jak otworze nie phpStormem tylko wejde po prostu w plik index.html to pokazuje się to samo, tylko zamiast 'http://localhost:63342' mamy 'null'
Poczytałem troche na temat tego błędu, ale nie łapie jak go okiełznać :)

Kombinuje jak koń pod góre na różne sposoby, ale mi coś nie idzie. Mógłbym prosić o drobne rozjaśnienie sprawy?

pozdrawiam i dzięki! ;)

edit:
a tak btw. jak mam success: function(data){..code..} to skąd javascript wie, że ma dane pobrane umiescić w tym "data" jako obiekt(dobrze rozumiem?) to jakas predefiniowana zmienna dla zapytan $.ajax(); gdzie wrzucane jest to co otrzyma z url?

A w ogóle wiem, że jQuery posiada getJSON(); i parseJSON(); - próbowałem, ale gdzieś musze robić błąd że nie bangla

0

http://www.doman.art.pl/kursjs/kurs/jquery/jquery_ajax.html

dodaj error: i sprawdź jakim błędem rzuca, jeśli success się nie wykonuje

0

@.AlDopisałem do ajaxa:

error:    (function(error) {
                console.log(error);
            })

konsola pokazuje cos takiego:
Obrazekjp_exwhqrr.jpg

0

dopisz tak jak w tym tutorialu:

type     : "GET",

i może zmień to:

dataType: "json",
0

@.Al niestety próbowałem i nic nie pomogło, zmieniałem też na POST, probowałem rozne dataTypes, dodawałem do headers: ten nagłówek Access-Control-Allow-Origin na pare sposobów jakie odnalazłem w google i nic :P

0
$.getJSON('target.php', { name: value}, function(data) { //target.php?name=value
     //data.Data;
});

Mi działa coś takiego na przykład.

echo json_encode($ArrToReturn);	
0

Hmm no tak, tylko wtedy operujesz na stringach po znaku ? w url, a mnie chodzi o to, żeby to co REST zwraca w postaci JSONa jakos przekonwertować i zapisać do obiektu JS(albo tablicy obiektów jeśli jest ich więcej) i potem np wyswietlic jakos na stronie :)
Próbowałem też tak jak ty mówisz $.getJSONem ale niestety nie poszło po mej myśli :D

0

blad spowodowany jest tym ze probujesz wywolac dane z innej domeny na co ajax domyslnie nie zezwala. ustaw w ajaxie:
crossdomain na true
datatype na jsonp
i powinno smigac

0

@szalonyfacet po zmianach w ajax wyglada to tak:

$.ajax({
            url: 'http://localhost:8080/main/users',
            dataType: "jsonp",
            type: "GET",
            crossDomain: true,
            success: (function(data){
                $('#tabela').append('<tr><td>' + data.name + '</td><td>' + data.lastame + '</td></tr>');
            }),
            error: (function(error) {
                console.log(error);
            })
        });

I tak: w przeglądarce teraz mam:

Uncaught SyntaxError: Unexpected token :

A jak zmienie dataType: na samo json to wywala ten sam błąd co wcześniej :)

Jeszcze coś przychodzi do głowy? Tak właściwie JSONP i JSON są kompatybilne w uzywaniu jeden zamiast drugiego i vice versa?

0

O boże. @szalonyfacet byś chociaż wyjaśnił na czym polega JSONP. @azalut: JSONP będzie wymagał od Ciebie modyfikacji zwrotki (nie czytałem całego tematu, nie wiem co masz pod tym localhostem:8080), podobnie jak dodanie nagłówka Access-Control-Allow-Origin, a co ułatwi działania. Doczytaj co to JSONP i co to Access-Control-Allow-Origin, wybierz co dla Ciebie lepsze.

0

to juz spiesze z wyjasnieniem i poprawieniem niedociagniec:

JSONP (JSON with Padding) jest to zmodyfikowana wersja danych typu JSON, ktora zostala spreparowana na potrzeby wymiany danych miedzy roznymi domenami (taki json dla cross-domain). Oczywiscie jak wspomnial @dzek69 a nie zrobilem tego ja (mea culpa) musisz zmodyfikowac (ale tylko lekko) serwowane dane z serwera z:

{"name":"Maciej","lastname":"NowyJedenUser"}
nazwaFunkcji({"name":"Maciej","lastname":"NowyJedenUser"})

a po stronie klienta dodaj jeszcze "?callback=?" na koncu adresu URL.

Tutaj dosyc zwiezel to opisali na kilka sposobow:
http://stackoverflow.com/questions/5943630/basic-example-of-using-ajax-with-jsonp

0

@dzek69 @szalonyfacet czyli schemat wygląda mniej-wiecej tak:
Moj serwer zwraca czystego JSON'a, klient go pobiera, konwertuje na JSONP i wtedy dopiero konwertuje na obiekt JavaScriptu?

Troche mnie dziwi, że to sie tak komplikuje :D na tutorialu z spring.io: (dokladniej ten: http://spring.io/guides/gs/consuming-rest-jquery/ ) nie musze robić nic zwiazanego z JSONP. Tam po prostu z założenia powinien działać.

Aktualnie plik html wyglada tak:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.0.min.js"></script>
</head>
<body>
<script>
    $(document).ready(function(){
        $.ajax({
            url: 'http://localhost:8080/main/users?callback=?',
            dataType: "jsonp",
            crossDomain: true,
            success: (function(data){
                $('#tabela').append('<tr><td>' + data.name + '</td><td>' + data.lastame + '</td></tr>');
                alert("wyszlo!");
            }),
            error: (function(error) {
                console.log(error);
            })
        });
    });
</script>

<table id="tabela" style="border: 1px solid black;">
    <tr><td>Test</td></tr>
</table>

</body>
</html>

i otrzymuje pod F12 w chromie:

GET http://localhost:8080/main/users?callback=jQuery111009289290052838624_1397560257451&_=1397560257452 net::ERR_CONNECTION_REFUSED

1

masz dwa wyjscia jak wspomnial dzek:

  • ustawic serwer by zezwalal na cross domain: http://enable-cors.org/server.html i potem pracowac na czystym jsonie nie martwiac sie co to jsonp i jak to wlaczyc lub:
  • operowac na jsonp czyli to co po czesci juz masz, ale zapomniales opakowac dane z serwera tak jak napisalem w poprzednim poscie (czyli zamaist wysylania czystego json musisz troche zmodyfikowac i wyslac JSONP, jak? napisalem w poprzednim poscie.
0

@szalonyfacet hmm no tak, chodzi o to, żeby dane jsona opakować do funkcji z jakąś nazwą, tylko pytanie jak to zrobic :) bo rozumiem, że callback= przyjmie wartość ktora bedzie nazwą tej wlasnie funkcji?

jesli chodzi o 2 wyjscie: operować na JSONP ale w całości - tzn serwer wysyła JSONP, java script przetwarza JSONP i w ogóle wszystko dzieje się w obrębie JSONP - czy chodzi o to, że serwer wysyła czystego JSON, a w javascripcie sobie przed operowaniem na danych konwertuje to do czystego JSON'a?

**EDIT:**
@szalonyfacet udało sie! :) Tym drugim sposobem. gdzies w goglach wyszperałem, że ktoś stworzył prosty filtr z javax.servlet.Filter i filtruje. Zrobilem tak samo, zmapowałem ten servlet na /* czyli każdy url bedzie obsłużony. Teraz już jQuery odbiera i wyświetla użytkownika.

Zastanawia mnie jednakże, choć nie wiem czy na to pytanie to dobry dział: Dlaczego przez filtr responsa i dodanie do niego nagłówka Access-Control-Allow-Origin wszystko działa, a jak dodam do kontrolera Springa cos takiego:

 
@RequestMapping(value = "/users", method = RequestMethod.GET, headers = {"Accept=application/json", "Access-Control-Allow-Origin=*"})
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public User getUsers(){
        return userService.returnOneUser();
    }

To już nie działa? O co tutaj się rozchodzi?:P

Dla przyszłych pokoleń link który mi pomogł:

Mój ajax wyglada tak:

 
$.ajax({
            url: 'http://localhost:8080/main/users',
            success: (function(data){
                $('#tabela').append('<tr><td>' + data.name + '</td><td>' + data.lastname + '</td></tr>');
            }),
            error: (function(error) {
                console.log(error);
            })
        });

Filtr tak:

package com.maciej.filters;

import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class CROSFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        resp.setHeader("Access-Control-Allow-Origin", "*");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
    }
}
1

dla twojej potrzeby zostaw jak jest. tym parametrem moglbys zdefiniowac jaka funckaj ma sie odpalic po zwroceniu zadania. tutaj masz przyklad: http://jsbin.com/fahitexi/1/edit

by zobaczyc jak wypuscic dane po stroinie serwera: https://api.github.com/?callback=jakasnazwafunkcji

ta jakas nazwa funckji to tylko dlatego zeby api githuba dobrze wygenerowalo dane, tobie i skryptowi wystarczy "?" w adresie

0

@szalonyfacet czyli parametr callback jest po to, zeby JS nadał funkcji nazwę, i w ta funkcje "opakowane" będą dane JSON'a z czego powstanie JSONP i jego wlasnie otrzymam?

A mógłbyś dokładniej wyjaśnić o co chodzi z przykładem pod adresem: http://jsbin.com/fahitexi/1/edit bo nie do końca rozumiem :D?

Jak już pobrałem dane JSON w postaci jednego prostego obiektu, to teraz zastanawiam się jak odebrać jQuery cos takiego:
[{"name":"Maciej","lastname":"Maciejowicz"},{"name":"Bartosz","lastname":"Bartoszewski"},{"name":"Andrzej","lastname":"Grzyb"},{"name":"Antoni","lastname":"Rewinski"},{"name":"Adam","lastname":"Ratkiewicz"}]
jest to zwrocone jako lista obiektów User z controllera springa. Powstaje mi stąd cos takiego jak dałem wyżej i próbuje to teraz jakos odczytać zeby zapisac jako.. lista obiektów? w javascript, albo wyswietlic w tabeli itd. Pytam o to tylko tak btw, jako ze juz jestesmy w temacie ;)

#edit
a żeby nie byc gołosłownym to powstało do tej pory coś takiego:

 
var objects = [];
        $.ajax({
            url: 'http://localhost:8080/main/users',
            success: (function(data){
                var singleObj = {};
                $.each(data, function(key, val){
                    singleObj[key] = val;
                    $('#tekst').append(singleObj.name + " " + singleObj.lastname);
                });
                objects.push(singleObj);
            }),
            error: (function(error) {
                console.log(error);
            })
        });

ale zwraca: undefined undefinedundefined undefinedundefined undefinedundefined undefinedundefined undefined

           **EDIT**

Co do tego pytania które zadałem przy okazji, rozwiązałem problem w ten sposób:

success: (function(data){
                for(var i=0; i<Object.keys(data).length; i++){
                    $('#tabela').append('<tr><td>'+data[i].name+'</td><td>'+data[i].lastname+'</td></tr>');
                }

            }),

Zastanawia mnie jednak: jakiego typu jest zmienna 'data'? to jest tablica obiektów? czy jak to rozumieć?

0

jakiego typu jest zmienna 'data'? to jest tablica obiektów? czy jak to rozumieć?

  1. https://api.jquery.com/jQuery.ajax/ (szczególnie fragment z "dataType", którego nie zdefiniowałeś)
  2. console.log

Z każdym nowym postem widzę u Ciebie totalny brak samodzielności i prób wyszukiwania informacji. Daleko nie zajdziesz, jeżeli całe aplikacje będziesz tworzyć na takiej zasadzie, że z co drugą linijką na forum ;)

0

tak wlasciwie to szukam, tylko jako ze jest temat juz to przy okazji pytam o jakies tam szczegoly, zeby nie nabrac jakichs zlych nawykow :) czasem sie zdarzy tak jak teraz, ze szukam, szukam i znalezc nie moge i tworze posta, bo nie wpadlbym na to ze chodzi np o cross domain
Generalnie wszystko juz zdaje sie jasne. Co do typu szukalem pod tym linkiem ktory podales ale w zlym miejscu :D

dzieki za wszystko, pomogliscie mi bardzo @dzek69 @szalonyfacet ;)

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