No matter what I try I continue to get error:
"Access to XMLHttpRequest at 'file:///C:/api/v1/backtest?{%22strategy_name%22:%22sma"}' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https."
Here is the ajax call:
        var inputs = {};
        inputs.strategy_name = strategy_name;
        inputs.start_date = document.getElementById("start_date").value;
        inputs.end_date = document.getElementById("end_date").value;
        inputs.formula = document.getElementById("formula").value;
        inputs.symbol = document.getElementById("backtest_symbol").value
        inputs.benchmark_symbol = document.getElementById("benchmark_symbol").value
        let jsonStrategyInputs = JSON.stringify(inputs);
        console.log("jsonStrategyInputs=",jsonStrategyInputs);
    $.ajax({
        type        : "GET",
        contentType : "application/json",
        datatype    : "json",    
        url         : "/api/v1/backtest",
        data        : jsonStrategyInputs,
        success     : function(data){
            //do a bunch of business logic
        },
        error: function(e) {      
            alert('Error: '+e);
        }
    });
Here is the Spring Boot controller code:
@CrossOrigin(origins = "*")
@RestController
@RequestMapping(path="/api/v1")
public class StrategyController {
    @Autowired
    private StrategyService strategyService;
    @GetMapping(value = "/backtest")
    @ResponseBody
    public JsonResponse backtestStrategy(@RequestBody BacktestInputs inputs, BindingResult result) throws Exception {
bla bla
}
This gives noted exception. So I added this class to the project:
@Component
public class SimpleCORSFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        response.setHeader("Access-Control-Expose-Headers", "Location");
        chain.doFilter(req, res);
    }
    @Override
    public void init(FilterConfig filterConfig) {}
    @Override
    public void destroy() {}
}
Same error. I have tried countless combinations of similar post answers but still no luck. Back to the experts. Any suggestions?
Of note, calling a similar controller with a jquery method works fine, like this:
function loadWatchlist() {
    $.getJSON("http://localhost:8080/api/v1/watchlist?name=My%20Portfolio", function (data) {
        data.forEach(function (item) {
            console.log(item.watchlistId.symbol);
    });
}
EDIT Interestingly, if I click the link in the browser console, it says "Invalid character found in the request target [/api/v1/backtest?{%22strategy_name%22:%22sma-cross-and-extreme-hi-lo%22,%22start_date%22:%221928-12-30%22,%22end_date%22:%222020-06-19%22,%22formula%22:%22LET%20InitialBuyStop=StopLoss(InitialBuy,H)\nLET%20TrailingBuyStop=StopLoss(TrailingBuy,5%)\nLET%20InitialSellStop=StopLoss(InitialSell,L);\nLET%20TrailingSellStop=StopLoss(TrailingSell,5%)\nLET%20CrossAboveSMA200=C(1)%3CSMA(200,1)%20AND%20C%3ESMA(200)\nLET%20CrossBelowSMA200=C(1)%3ESMA(200,1)%20AND%20C%3CSMA(200)\nLET%20AboveUpperEnvCh=C%3EEnvCh(200,20).Upper\nLET%20BelowLowerEnvCh=C%3CEnvCh(200,20).Lower\nLET%20YesterdayWasOut=Position(1)==0\nLET%20YesterdayWasIn=Position(1)==1\nLET%20HitBuyStop=C%3EBuyStop\nLET%20HitSellStop=C%3CSellStop\nIF(CrossAboveSMA200)%20THEN%20BUY\nIF(CrossBelowSMA200)%20THEN%20SELL\nIF(AboveUpperEnvCh%20AND%20DnBar%20AND%20YesterdayWasIn)%20THEN%20SellAndSetBuyStop\nIF(AboveUpperEnvCh%20AND%20HitBuyStop%20AND%20YesterdayWasOut)%20THEN%20BuyAndResetStops\nIF(BelowLowerEnvCh%20AND%20YesterdayWasOut%20AND%20UpBar)%20THEN%20BuyAndSetSellStop\nIF(BelowLowerEnvCh%20AND%20YesterdayWasIn%20AND%20HitSellStop)%20THEN%20SellAndResetStops\nIF(TrailingBuyStop%3CBuyStop)%20THEN%20BuyStop=TrailingBuyStop\nIF(TrailingSellStop%3ESellStop)%20THEN%20SellStop=TrailingSellStop%22,%22symbol%22:%22SPP-500%22,%22benchmark_symbol%22:%22SP-500%22]"
It seems it is only url encoding the spaces and not {}, (), '=', '-' or the '%' in the 5%. May be I should not use JSON.stringify(inputs)? I also added more relevant info in this post above the ajax call.
 
    