-2

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.

user3217883
  • 1,216
  • 4
  • 38
  • 65
  • 1
    It seems that ajax request is not sent to server using a valid url (file:///C:/api/v1/backtest?...). Shouldn't it be something like `http://localhost:8080/api/v1/backtest.....`? Have you tried specifying explicitly the url? – lzagkaretos Dec 25 '20 at 07:54
  • I tried that but same error. I can call the backend directly and it works. Calling from the front end fails. Also, using $.getJSON works. Something different about the ajax call. – user3217883 Dec 25 '20 at 15:32

1 Answers1

-2

the error you get is caused by your Chrome browser, so @CorssOrigin in the backend is no use. this is cased since your ajax code is trying to access your own local resource. to avoid this, you need to add some options when you execute Chrome browser. here's a sample for executing Chrome on Windows

"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="C:\Users\ユーザ名\Local\Google\Chrome\User Data"
guchuan
  • 125
  • 1
  • 10
  • you can clearly see that his intent is to call the backend server and not to read a file from disk. To avoid this he does not need to disable all web security in chrome. He needs to make sure that his angular app is properly configured to send the request to `http://localhost:8080` and not to `file:///C:/`. Disabling all web security should almost never be done, even if its only for local development. – Toerktumlare Dec 25 '20 at 08:31
  • I changed the uri to 'http://localhost:8080/api/v1/backtest' instead of just '/api/v1/backtest' but result was the same. The index file that is calling this is "file:///C:/Users/Greg/Projects/moneymachine/src/main/resources/static/index.html". And this is not an Angular project. – user3217883 Dec 25 '20 at 15:04